 (  README                                                                                                 644     322     145         7065  3740013223   5010                                                                                                                                                                                                                                                                                                                                                                      
	Communication Machinery Corporation
	TCP Release 2.1.5
	[September 30, 1986]

Greetings!

	This is the Release 2.1.5 of Communication Machinery
Corporation's TCP/IP networking software specific to Unix System V.

	This release of TCP/IP requires ENP KERNEL version 3.6
or later.  Check the PROMS on your ENP for the current revision
number of the Kernel.  If you feel that the revision level of your
Kernel is earlier than 3.6, please call the CMC Technical Support at
(805) 963-9471.

	Included with the release are the Telnet, FTP, rsh, rcp, and
rlogin user-level protocols, as well as the utilities for using various
data bases of host names and services.  Future releases will expand
the range of user-level applications.

	You are receiving source code for all the user-level software,
including the interface routines to the network device driver.  The
driver presents an interface which matches exactly the syntax of
the 4.2BSD "socket" calls; 4.2 semantics are either matched exactly
or not present -- there are no partial semantic changes.

	Also included is source for the Unix device driver which 
handles the ENP.  A new pseudo-teletype driver is also included;
this is a true Sys V tty driver which provides the "packet" mode
of 4.2BSD.  It is functionally compatible (and interoperable) with
other such drivers, but is NOT ioctl compatible; to use it successfully
you must use the ioctl's from <CMC/pty.h>.

	The protocol software that runs on the ENP is provided in
an ASCII representation of its binary form.  A downloader is also provided,
as is a means of specifying both Ethernet and Internet addresses for the
Node Processor.

	Following is a brief tour of the distribution tape.

./enp:
	This directory contains the binary code to load into the
	ENP.  It also includes samples showing how to specify your
	host's Internet address to the ENP.

./unix:

./unix/etc:
	This contains example copies of the data base files used
	for host names, services, port numbers and the like.  The
	host table is somewhat out of date copy of the one used
	at CMC; you will need to add entries for your hosts.

./unix/include:

./unix/include/CMC:
	Include files used by various pieces of software.  In general,
	the version here should be used in preference to a similarly
	named one already on your system.

./unix/lib:
	This collection of routines provides the interface to the
	network device driver, the network data bases, and general
	routines for manipulating network addresses.

./unix/man:
	Man pages for all this.  The shell script prman is useful
	but not necessary for printing the new manual pages.

./unix/man/man1:

./unix/man/man3:

./unix/man/man4:

./unix/man/man5:

./unix/man/man8:

./unix/servers:
	Source for the telnet, ftp, rlogin, rsh and tftp daemons.
	Normally, these would reside in /etc or /etc/net, and be
	started up by /etc/rc.

./unix/servers/ftpd:

./unix/support:
	Source for the ENP download program.
		enpload enp0 enp_param.S enpcode.S
	where "enp0" is a magic literal, enp_param.S is an object file
	which defines various run-time parameters of the ENP, and
	enpcode.S is the supplied ENP-resident protocol software.

./unix/sys:
	Source for the four device drivers which comprise the modifications
	to your System V system.

./unix/users:
	Source for the user side telnet, ftp, rsh, rlogin, rcp and
	tftp programs.

./unix/users/ftp:


	There are Makefiles and README files in several places;
examine these before using them, as our conventions may not suit
your needs.

	If you have any difficulties with this software distribution,
please contact CMC Technical Support at (805) 963-9471.

                                                                                                                                                                                                                                                                                                                                                                                                                                                                           enp/                                                                                                   750     322     145            0  3756741230   4625                                                                                                                                                                                                                                                                                                                                                                      enp/README                                                                                             644     322     145         2040  3621344271   5566                                                                                                                                                                                                                                                                                                                                                                      	This directory contains the software to be loaded into the
ENP.  It is in the form of S-records, a machine-independent character
representation of binary.  In normal use, enp_param.S and enpcode.S
would be copied to /etc or /etc/net, and loaded into the ENP by /etc/rc.
See the README file in ../unix/support for the downloading procedure.

configuration
	This is a textual description of your system.  At a minimum
	you must supply the Internet address of you host, and the
	type of ENP you are using.  This file is processed by
	../unix/support/enpconfig to produce enp_param.S.

	Note that you will have to change configuration to specify the
	Internet address to use for your host.  Your address must be set
	to match your entry in /etc/hosts.

	There are provisions for dealing with byte-swapping or
	bus address mismatches, as well as allowing the ENP to perform
	DMA; see the Internet Manager's Guide for more details.

enpcode.S
	This is the protocol processing software to be loaded into
	your ENP.

ldenp
	An example of how to download the ENP.
o included is source for the Unix device driver which 
handles the ENP.  A new pseudo-teletype driver is also included;
this is a true Sys V tty driver which provides the "packet" mode
of 4.2BSD.  It is functionally compatible (and interoperable) with
other such drivers, but is NOT ioctl compatible; to use it successfully
you must use the ioctl's from <CMC/pty.h>.

	The protocol software that runs on the ENP is provided in
an ASCII representation of its binary form.  A downloenp/download_enp                                                                                       544     322     145           44  3621344272   7244                                                                                                                                                                                                                                                                                                                                                                      
enpload enp0 enp_param.S enpcode.S
e to be loaded into the
ENP.  It is in the form of S-records, a machine-independent character
representation of binary.  In normal use, enp_param.S and enpcode.S
would be copied to /etc or /etc/net, and loaded into the ENP by /etc/rc.
See the README file in ../unix/support for the downloading procedure.

configuration
	This is a textual description of your system.  At a minimum
	you must supply the Internet address of you host, and the
	type of ENP you are using.  This fienp/Makefile                                                                                           444     322     145          104  3621344272   6324                                                                                                                                                                                                                                                                                                                                                                      enp_param.S: enp_param.desc
	enpconfig enp_param.desc > enp_param.S
 is in the form of S-records, a machine-independent character
representation of binary.  In normal use, enp_param.S and enpcode.S
would be copied to /etc or /etc/net, and loaded into the ENP by /etc/rc.
See the README file in ../unix/support for the downloading procedure.

configuration
	This is a textual description of your system.  At a minimum
	you must supply the Internet address of you host, and the
	type of ENP you are using.  This fienp/enp_param.desc                                                                                     444     322     145         1070  3621344273   7512                                                                                                                                                                                                                                                                                                                                                                      # Sample ENP parameter file

# You must set your host name in the line that starts "host".
# You may optionally specify an Ethernet address on the "host" line;
# if none is specified, the Ethernet address on the ENP will be used.

# You must specify the number of your ENP board, e.g. 10, 20, 30, etc.

# It is recommended that in general operation you run with the 0x10 bit
# of flags set.  This reduces load in the ENP somewhat by not attempting
# to print messages on the ENP console.

host "your_host_name_go (   (  es_here"
enp your_ENP_model_number_goes_here
flags 0x10
me in the line that starts "host".
# You may optionally specify an Ethernet address on the "host" line;
# if none is specified, the Ethernet address on the ENP will be used.

# You must specify the number of your ENP board, e.g. 10, 20, 30, etc.

# It is recommended that in general operation you run with the 0x10 bit
# of flags set.  This reduces load in the ENP somewhat by not attempting
# to print messages on the ENP console.

host "your_host_name_goenp/contents                                                                                           640     322     145           64  3754217122   6427                                                                                                                                                                                                                                                                                                                                                                      rw-r-----210/101  98520 Sep 30 11:10 1986 enpcode.S
x10
me in the line that starts "host".
# You may optionally specify an Ethernet address on the "host" line;
# if none is specified, the Ethernet address on the ENP will be used.

# You must specify the number of your ENP board, e.g. 10, 20, 30, etc.

# It is recommended that in general operation you run with the 0x10 bit
# of flags set.  This reduces load in the ENP somewhat by not attempting
# to print messages on the ENP console.

host "your_host_name_goenp/enp_param.S                                                                                        640     322     145          157  3756741171   6770                                                                                                                                                                                                                                                                                                                                                                      S210F011000000000000F0112000000010BD
S210F0110C000000000000000000000000E2
S210F01118000000000000000059000088F5
 specify an Ethernet address on the "host" line;
# if none is specified, the Ethernet address on the ENP will be used.

# You must specify the number of your ENP board, e.g. 10, 20, 30, etc.

# It is recommended that in general operation you run with the 0x10 bit
# of flags set.  This reduces load in the ENP somewhat by not attempting
# to print messages on the ENP console.

host "your_host_name_goenp/enpcode.S                                                                                          640     322     145       300330  3740012616   6503                                                                                                                                                                                                                                                                                                                                                                      S210F020004E56FFF448EE3080FFF44247E6
S210F0200C600252470C4707D06DF8287CA5
S210F0201800F09CC860044294588CB9FCA0
S210F0202400F0B3B665F4527900F09B941F
S210F0203023FC00F0110000F09CD8207992
S210F0203C00F09CD84A90673442476020C1
S210F02048207900F09CD82010320748C128
S210F02054D0812040300748C0068000F025
S210F0206090702240129052470C47000689
S210F0206C6DDA0079400000F09054600837
S210F020780279BFFF00F09054207900F0D1
S210F020849CD84AA80004670A20680004F4
S210F0209023D000F09CEE207900F09CD8E5
S210F0209C4AA8000C670A2068000C23D04D
S210F020A800F097A423F900F0100400F0FC
S210F020B49CD42F3C00F09054207900F0F3
S210F020C09CD44E90588F2A40424760187F
S210F020CC300748C0D08D2040300748C0D8
S210F020D8068000F09CDC2240129052477C
S210F020E40C4700066DE223ED000800F04B
S210F020F09CE223ED000C00F09CF223EDC7
S210F020FC001000F09CFE23ED001400F035
S210F021089CC823F900F091D600F09CF67D
S210F0211423F900F091DA00F09CFA4EB9C6
S210F0212000F07A384EB900F028904EB966
S210F0212C00F07CC0207900F09CD8302831
S210F02138000A028000000010670642A7B4
S210F0214442A7600C2F3C00EF80112F3CEF
S210F0215000EF80244EB900F022F0508F13
S210F0215C42A74EB900F02E18588F2079DC
S210F0216800F09CD84AA8001067182079F8
S210F0217400F09CD82F2800102F3C00F044
S210F0218090784EB900F023F8508F2F3CFA
S210F0218C00F0907D4EB900F023F8588F5C
S210F021982F3900F09CEE2F3C00F0909ADF
S210F021A44EB900F023F8508F2F3C00F0EE
S210F021B090AB4EB900F023F8588F424771
S210F021BC6022300748C0068000F09CDC73
S210F021C82040700010102F002F3C00F09C
S210F021D490B84EB900F023F8508F524738
S210F021E00C4700066DD82F3900F097A4CD
S210F021EC2F3C00F090BC4EB900F023F839
S210F021F8508F2F3C00F090D64EB900F04F
S210F0220423F8588F23FC00F09CE600F056
S210F022109CCC4EB900F08C904CEE308068
S210F0221CFFF44E5E4E7500004E560000BB
S210F022284A2FFF7C48EE000000004EB984
S210F0223400F02BE0600000024CEE000012
S210F0224000004E5E4E7500004E56FFF893
S210F0224C2F072F061E2E000B303900F076
S210F0225890F802800000000167320C07CE
S210F02264000A660C2F3C0000000D610024
S210F02270FFD8588F3C3C0400600E20792C
S210F0227C00F09D3808100002660653467D
S210F022884A466EEE207900F09D4010876C
S210F022942C1F2E1F4E5E4E754E56FFFCA3
S210F022A02F074207303900F090F802805B
S210F022AC000000016732203900F090FAC4
S210F022B8B0B900F090FE6724207900F02A
S210F022C490FE1E1052B900F090FE0CB90F
S210F022D000F09D3400F090FE660A23FC3F
S210F022DC00F09D0200F090FE1007488015
S210F022E848C02E1F4E5E4E754E56FFF896
S210F022F42F072F062E2E00082C2E000CB4
S210F023004A876712200752802F004EB963
S210F0230C00F02848588F4A806608427996
S210F0231800F090F8606423C700F09D34DD
S210F023242007568023C000F09D382007EC
S210F02330568023C000F09D3C2007528031
S210F0233C23C000F09D4023FC00F09D0242
S210F0234800F090FE23F900F090FE00F08C
S210F0235490FA2F062F074EB900F027B8BD
S210F02360508F33FC000100F090F82F3C8A
S210F0236C0000000A42A72F3C00F0238A75
S210F023784EB900F07D1CDEFC000C2C1FA3
S210F023842E1F4E5E4E754E56FFFC2F07C7
S210F02390207900F09D381E1008070000B1
S210F0239C673A207900F09D401E10207972
S210F023A800F090FA108752B900F090FA9E
S210F023B41007488048C02F006100FE8A29
S210F023C0588F0CB900F09D3400F090FA35
S210F023CC660A23FC00F09D0200F090FA78
S210F023D82F3C0000000A42A72F3C00F04B
S210F023E4238A4EB900F07D1CDEFC000CD5
S210F023F02E1F4E5E4E7500004E56FF7815
S210F023FC2F0D2F074BEEFF80486E000CF4
S210F024082F2E0008485561000040DEFC56
S210F02414000C2E006010101D488048C020
S210F024202F004EB900F02248588F20071D
S210F0242C53874A806EE82E1F2A5F4E5E33
S210F024384E754E5600002F2E00102F2E72
S210F02444000C6100FFB0508F4E5E4E752D
S210F024504E56FFF048EE30C0FFF0286E4D
S210F0245C001023EE000800F0912A603813
S210F024684A87660E203900F0912A90AEEC
S210F0247400086000020A207900F0912AAF
S210F02480108752B900F0912A0C8700007B
S210F0248C000A6610207900F0912A10BCBF
S210F02498000D52B900F0912A202E000C26
S210F024A452AE000C20401010488048C0DB
S210F024B02E000C800000002566AE206EAA
S210F024BC000C1010488048C02E0052AEF5
S210F024C8000C427900F0912E0C8700000A
S210F024D400316D260C87000000396E1EEB
S210F024E0200704800000003033C000F03D
S210F024EC912E206E000C1010488048C0A6
S210F024F82E0052AE000C2C1420070C80B6
S210F02504000000636700010C6E00013060
S210F025100C8000000044670000900C8077
S210F0251C0000004C670000A00C800000DF
S210F02528004F670000960C800000005585
S210F025346700008C0C8000000058670068
S210F025400082207900F0912A108752B932
S210F0254C00F0912A588C6000FF4C4A9476
S210F025586C16207900F0912A10BC002DC3
S210F0256452B900F0912A20144480288020
S210F025700C870000006C67080C87000069
S210F0257C007566027E642007E480028092
S210F0258800000003E580068000F09108DB
S210F025942040201033C000F091042F14FB
S210F025A0610000EA588F60A84A866C16AE
S210F025AC207900F0912A10BC002D52B9E6
S210F025B800F0912A200644802C000C87CE
S210F025C40000004C67080C870000005573
S210F025D066027E442007E48002800000D3
S210F025DC0003E580068000F09108204027
S210F025E8201033C000F091062F066100B2
S210F025F4012860AC2A54101D488048C036
S210F026002E006700FF4C207900F0912AB5
S210F0260C108752B900F0912A60E42079A3
S210F0261800F0912A10AC000352B900F05C
S210F02624912A0C940000000A6600FF22C9
S210F02630207900F0912A10BC000D60002C
S210F0263CFF0E0C800000006F6700FF2A05
S210F026486E180C80000000646700FF04B1
S210F026540C800000006C6700FF146000B3
S210F02660FEE20C8000000073678E0C8019
S210F0266C000000756700FEFE0C80000009
S210F0267800786700FEF46000FEC24CEE36
S210F0268430C0FFF04E5E4E754E56FFF470
S210F0269048EE20C0FFF43E2E000A2A7C24
S210F0269C00F091447000300780F900F068
S210F026A89104484002800000FFFF06800E
S210F026B400F0911820401B10700030075A
S210F026C080F900F0910402800000FFFF9B
S210F026CC3E0066D00C79000A00F0910485
S210F026D866047020600270303C00600267
S210F026E41B06203C00F09144908D32392B
S210F026F000F0912E48C1B0816C1060E83C
S210F026FC207900F0912A109D52B900F0F1
S210F02708912ABBFC00F0914465EA4CEE10
S210F0271420C0FFF44E5E4E754E56FFF4EB
S210F0272048EE20C0FFF42E2E00082A7CA5
S210F0272C00F091447000303900F0910687
S210F027382F002F074EB900F08FBC508F1A
S210F02744068000F0911820401B1070007A
S210F02750303900F091062F002F074EB92C
S210F0275C00F08F48508F2E0066CA700008
S210F02768303900F091060C800000000AEA
S210F0277466047020600270302C006002DA
S210F027801B06203C00F09144908D32398E
S210F0278C00F0912E48C1B0816C1060E89F
S210F02798207900F0912A109D52B900F054
S210F027A4912ABBFC00F0914465EA4CEE74
S210F027B020C0FFF44E5E4E754E56FFEC57
S210F027BC48EE30E0FFEC2E2E00082C2E2D
S210F027C8000C2A7C00F091446010101504
S210F027D4488048C0D087284018AD0001AF
S210F027E0548D203900F0915AE3800680FA
S210F027EC00F09144BBC065DE4AB900F076
S210F027F8919A66422A7C00F0915E601018
S210F028041015488048C0D086284018AD5B
S210F028100001548D203900F09196E38012
S210F0281C068000F0915EBBC065DE2A3C32
S210F0282800007FFF600253854A856EFAC0
S210F0283423FC0000000100F0919A4CEE2E
S210F0284030E0FFEC4E5E4E75206F00049A
S210F0284C40E746FC270023F900000008D7
S210F0285800F091A023FC00F0287C0000AB
S210F028640008203CFFFFFFFF4A1023F99D
S210F0287000F091A00000000846DF4E7556
S210F0287C4280DFFC000000082F7C00F01B
S210F02888286E00024E7300004E56FFF063
S210F0289448EE3880FFF0303900F091D4A8
S210F028A0C1FC00302F002F3C00F09D48DB
S210F028AC2F3C00F091A44EB900F08CAA6E
S210F028B8DEFC000C303900F091D448C073
S210F028C45380C1FC0030068000F09D48F8
S210F028D026407E016000009870001007A3
S210F028DC5380C1FC0030068000F09D48E0
S210F028E82840268C264C1947002242ACF3
S210F028F40024422C00232F2C00104EB9BC
S210F0290000F08A38588F394000182F2C51
S210F0290C00144EB900F08A385 (   (  88F39409D
S210F02918001A306C001C48504EB900F05D
S210F029247AF2588F2A40306C001C4850A5
S210F0293048554EB900F08D00508F2ABCC0
S210F0293C00123456294D001E302C001CF2
S210F0294848C081FC000448C05380E580C5
S210F02954DBC0294D00284295598D202C40
S210F0296000042A809AFC0038294D002C58
S210F0296C520770001007B07900F091D40C
S210F029786300FF5E13FC000100F09D7889
S210F0298423FC00F09D4800F09D7A42799C
S210F0299000F091F8203900F09D7A0680E7
S210F0299C0000002823C000F09CD04CEE99
S210F029A83880FFF04E5E4E754E56FFF87D
S210F029B42F0D207900F09D7A2068001EA0
S210F029C00C9000123456670E2F3C00F00E
S210F029CC91FA4EB900F08B04588F4EB90B
S210F029D800F08C7C2D40FFFC207900F015
S210F029E49D7A2A506034203900F09D7A6D
S210F029F006800000002823C000F09CCCFD
S210F029FC41ED002823C800F09CD023CD4D
S210F02A0800F09D7A13ED002200F09D789F
S210F02A144EB900F08C9060322A55102D60
S210F02A2000230280000000076716102D4F
S210F02A2C00230280000000FE0C400008B2
S210F02A3866E2022DFFF60023BBF900F06A
S210F02A449D7A66A2527900F091F82F2ED1
S210F02A50FFFC4EB900F08C88588F2A5F0F
S210F02A5C4E5E4E754E56FFFC2F071E2EE9
S210F02A68000B4A076608203900F09D7A43
S210F02A74602A70001007B07900F091D4D2
S210F02A80630E2F3C00F092104EB900F0F0
S210F02A8C8B04588F700010075380C1FCBC
S210F02A980030068000F09D482E1F4E5EB9
S210F02AA44E754E56FFF82F0D2F0C2A6EC4
S210F02AB00008200D6608103900F09D7834
S210F02ABC602E4A1567F4287900F09D7A29
S210F02AC8486C000848554EB900F0891C18
S210F02AD4508F4A806606102C0022600C22
S210F02AE02854B9F900F09D7A66DE42003A
S210F02AEC285F2A5F4E5E4E754E560000C6
S210F02AF87000102E000B2F006100FF5E37
S210F02B04588F50802F002F2E000C4EB97A
S210F02B1000F08950508F4E5E4E754E5609
S210F02B1CFFF048EE20E0FFF01E2E000B4D
S210F02B283C2E000E3A2E00127000100733
S210F02B342F006100FF28588F2A400C4646
S210F02B40D96C67043B4600180C45D96CB5
S210F02B4C67043B45001A022DFFFD002335
S210F02B584CEE20E0FFF04E5E4E754E5640
S210F02B64FFF82F0D2F071E2E000B700040
S210F02B7010072F006100FEEA588F2A4084
S210F02B7C206E000C30AD0018206E000C2F
S210F02B88316D001A00022E1F2A5F4E5E10
S210F02B944E754E56FFF82F0D2F071E2E24
S210F02BA0000B2A7900F09D7A102D002220
S210F02BACB0076726306D001A4850306DF8
S210F02BB800184850700010072F00610055
S210F02BC4FF56DEFC000C3B7C270F001ACE
S210F02BD03B6D001A00182E1F2A5F4E5EA8
S210F02BDC4E7500004E5600004EB900F09A
S210F02BE88C7C4EB900F0475E4EB900F051
S210F02BF446C44EB900F02C644EB900F058
S210F02C00883A4EB900F075AA4AB900F008
S210F02C0C92246704610000144AB900F03E
S210F02C189D7E67C84EB900F07FF860C0E3
S210F02C244E754E56FFFC2F0D601A2F2D3B
S210F02C30000C2F2D0008206D00044E90C4
S210F02C3C508F48554EB900F07C80588F41
S210F02C482F3C00F092244EB900F0810002
S210F02C54588F2A404A8066D22A5F4E5EF7
S210F02C604E7500004E56FFF82F0D2F0C9E
S210F02C6C0CB90000000100F09D8266002C
S210F02C78014E203900F099740680000030
S210F02C8401402F004EB900F0695A588F3E
S210F02C904A806722603C48554EB900F0C0
S210F02C9C79BA588F6014082D000600046A
S210F02CA866EC42A748554EB900F0470C09
S210F02CB4508F203900F099740680000064
S210F02CC001402F004EB900F06842588F1B
S210F02CCC2A404A8066D02F3900F0997438
S210F02CD84EB900F0695A588F4A80672405
S210F02CE460362F3C00000003306D00341A
S210F02CF048504EB900F0300C508F2840D1
S210F02CFC485548544EB900F02E8E508F0C
S210F02D082F3900F099744EB900F06842C4
S210F02D14588F2A404A8066CA203900F02A
S210F02D2099740680000000282F004EB9C1
S210F02D2C00F0695A588F4A806774600007
S210F02D38008E2F3C00000003306D0034CD
S210F02D4448504EB900F0300C508F28407C
S210F02D500C6D80040004660E48554854D4
S210F02D5C4EB900F02EBC508F604442A729
S210F02D687000302D00042F00302D0034D9
S210F02D7448C02F0048544EB900F02EEA7C
S210F02D80DEFC00106024082D00070004A4
S210F02D8C66AC3B7C0004003242A7302D01
S210F02D98003448C02F0048554EB900F03B
S210F02DA42F72DEFC000C203900F0997451
S210F02DB00680000000282F004EB900F04E
S210F02DBC6842588F2A404A8066C0285FA4
S210F02DC82A5F4E5E4E754E56FFFC2F0D37
S210F02DD4601E48554EB900F079BA588FD2
S210F02DE06012082D0006000466EC485552
S210F02DEC4EB900F02FCC60EA203900F061
S210F02DF899740680000001402F004EB9D0
S210F02E0400F06842588F2A404A8066D2E0
S210F02E102A5F4E5E4E7500004E56FFF82E
S210F02E1C2F0D2F0C202E0008E5800680FD
S210F02E2800F094682A402855601842A775
S210F02E342F3C0000010042A7206C001CA0
S210F02E404E90DEFC000CD8FC00204A94FB
S210F02E4C66E4285F2A5F4E5E4E754E5618
S210F02E58FFFC2F0D2F2E00084EB900F0E6
S210F02E6430DE588F2A404A80671842A7DC
S210F02E702F3C0000010142A7206D001C62
S210F02E7C4E90DEFC000C7001600270004E
S210F02E882A5F4E5E4E754E56FFFC2F0D76
S210F02E942F2E00084EB900F030DE588FEC
S210F02EA02A404A80670E2F2E000C206D92
S210F02EAC000C4E90588F600270FF2A5FFA
S210F02EB84E5E4E754E56FFFC2F0D2F2E72
S210F02EC400084EB900F030DE588F2A40AF
S210F02ED04A80670E2F2E000C206D0010BC
S210F02EDC4E90588F600270FF2A5F4E5E2A
S210F02EE84E754E56FFFC2F0D2F2E0008E6
S210F02EF44EB900F030DE588F2A404A80BD
S210F02F0067162F2E00142F2E00102F2E18
S210F02F0C000C206D001C4E90DEFC000C4B
S210F02F182A5F4E5E4E754E56FFF448EEF3
S210F02F243080FFF42A6E00082E2E000C01
S210F02F30526D0032302D003248C0E580B3
S210F02F3C068000F09468204028506004E6
S210F02F48D8FC0020202C0004B08762F4B7
S210F02F54202C0008B08765EC2F074855CD
S210F02F60206C00144E90508F4CEE308029
S210F02F6CFFF44E5E4E754E56FFF448EE35
S210F02F783080FFF42A6E00082E2E000CAD
S210F02F84536D0032302D003248C0E5805E
S210F02F90068000F0946820402850600492
S210F02F9CD8FC0020202C0004B08762F463
S210F02FA8202C0008B08765EC2F2E0010DF
S210F02FB42F074855206C00184E90DEFCED
S210F02FC0000C4CEE3080FFF44E5E4E75B8
S210F02FCC4E56FFF82F0D2F0C2A6E000852
S210F02FD80C6DFFFF00306724302D003039
S210F02FE448C0E78041ED0010D1C028483E
S210F02FF0536D00302F2C00044855205480
S210F02FFC4E90508F4A8067D4285F2A5F02
S210F030084E5E4E754E56FFF82F0D2F074B
S210F030142E2E0008202E000CE580068012
S210F0302000F0946820402A506004DAFCAF
S210F0302C0020202D0004B08762F4202D58
S210F030380008B08765EC20152E1F2A5FFC
S210F030444E5E4E754E56FFFC2F0D2A6EA9
S210F03050000848554EB900F030DE588FEE
S210F0305C2A5F4E5E4E754E56FFFC2F0DA0
S210F030682A6E00083B7CFFFF00304AAEEA
S210F03074000C67122F2E00102F2E000C00
S210F0308048556100000CDEFC000C2A5FD6
S210F0308C4E5E4E754E56FFF82F0D2F0CC2
S210F030982A6E0008526D0030302D00301B
S210F030A448C0E78041ED0010D1C028487D
S210F030B028AE000C296E00100004285F0B
S210F030BC2A5F4E5E4E754E56FFFC2F0D40
S210F030C82A6E00080C6DFFFF0030670455
S210F030D4536D00302A5F4E5E4E754E566F
S210F030E0FFF448EE3800FFF42A6E0008FB
S210F030EC287C00F09468602226546018DF
S210F030F848552F134EB900F0891C508F7D
S210F031044A806604200B6010D6FC002009
S210F031104A9366E4588C4A9466DA700025
S210F0311C4CEE3800FFF44E5E4E750000DE
S210F031284E754E754E56FFF82F0D2F0713
S210F031342A6E00082E2E000C48552F3C8A
S210F0314000F094FD61000048508F4855E8
S210F0314C4EB900F02FCC588F2E1F2A5FD3
S210F031584E5E4E754E56FFF82F0D2F07FA
S210F031642A6E00082E2E000C48552F3C5A
S210F0317000F0950361000018508F4855E1
S210F0317C4EB900F02FCC588F2E1F2A5FA3
S210F031884E5E4E754E754E56FFF448EE47
S210F031943080FFF42A6E0008286E000C55
S210F031A04A6C00326D080C6C0003003224
S210F031AC6F047E0460043E2C00323007F6
S210F031B848C0E580068000F094C020407F
S210F031C42F10300748C02F004854485524
S210F031D02F3C00F0950A4EB900F023F8F2
S210F031DCDEFC0014302C003048C0E78009
S210F031E841EC0010D1C02F2800042F107E
S210F031F42F3C00F095384EB900F023F8A0
S210F03200DEFC000C2F2C0008306C0006E2
S210F0320C48507000302C00042F002F14E7
S210F032182F3C00F0954B4EB900F023F868
S210F03224DEFC0014306C00344850306CB7
S210F03230000E4850306C000C48502F3C4C
S210F0323C00F0957B4EB900F023F8DEFCA5
S210F0324800102F3C00F095A34EB900F0EB
S210F0325423F8588F42476034300748C01B
S210F03260D0AC00082040700010102F00CA
S210F0326C2F3C00F095B54EB900F023F8AA
S210F03278508F0C470027660E2F3C00F02D
S210F0328495B94EB900F023F8588F524769
S210F032900C4700506DC62F3C00F095BBBC
S210F0329C4EB900F023F8588F4CEE30804E
S210F032A8FFF44E5E4E7500004E754E753D
S210F032B44E56FFF82F0D2F0C2A6E000867
S210F032C0302E000EC1FC0050D0B900F01B
S210F032CC9D8E2840526C000641ED003646
S210F032D82B4800083B7C0002003270001F
S210F032E4102E000F322D000402810000B6
S210F032F0008080812F002F3C00F034BAE4
S210F032FC48554EB900F03062DEFC000CC5
S210F03308026D00600004303900F095C241
S210F03314916D003442A72F3CFFFFFFFF36
S210F0332048554EB900F02F72DEFC000C91
S210F0332C285F2A5F4E5E4E754E56FFF48A
S210F0333848EE2880FFF42A6E0008302EC5
S210F03344000EC1FC0050D0B900F09D8EC9
S210F0335026404A53662448532F2E000CEB
S210F0335C2F3C00F095C84EB900F023F8A6
S210F03368DEFC000C48554EB900F02FCCEF
S210F03374588F70FF6030082B0006000138
S210F0338066EA3B6E000E00343E2D000C9A
S210F0338C48C748554EB900F063B0588FA3
S210F033984A80660C7EFF48554EB900F0E7
S210F033A42FCC588F20074CEE2880FFF44A
S210F033B04E5E4E754E56FFF048EE3C00A8
S210F033BCFFF00CAE00000100000C66589C
S210F033C84AB900F095C4670000E042B976
S210F033D400F095C42F3C00F095EE4EB9CA
S210F033E000F03048588F264023EB000425
S210F033EC00F095C00CB9FFFFFFFF00F0EA
S210F033F895C0670000B42F3C00F095FC78
S210F034042F3C0000010042A72F3C00F017
S210F0341095F54EB900F02EEADEFC001038
S210F0341C60000092302E000AC1FC005048
S210F03428D0B900F09D8E2A40286E0010EF
S210F03434246C0008202E000C0C80000019
S210F03440800E670A0C800000800F6736D4
S210F0344C60620C920000FFFF6612700039
S210F03458301252802F0048554EB900F09C
S210F034646A60508F4854203900F09974CC
S210F034700680000000702F004EB900F03F
S210F0347C67F8508F602E0C920000FFFFE7
S210F03488661048554EB900F06A84588F64
S210F034943940000E600C397CFFFF00048D
S210F034A0397C003E000E48544EB900F097
S210F034AC688C588F4CEE3C00FFF04E5E33
S210F034B84E754E56FFF82F0D2F0C2A6EA6
S210F034C400084855203900F09974068086
S210F034D0000000702F004EB900F067F806
S210F034DC508F7000102E000FC1FC005046
S210F034E8D0B900F09D8E2840536C000612
S210F034F4082E0007000F670A48544EB977
S210F0350000F0688C588F285F2A5F4E5E43
S210F0350C4E7500004E754E754E56FFF8DA
S210F035182F0D2F0C2A6E0008302E000E2F
S210F03524C1FC0050D0B900F09D8E28408D
S210F03530526C000641ED00362B480008F7
S210F0353C3B7C000300327000102E000FE5
S210F03548322D000402810000008080811B
S210F035542F002F3C00F0371A48554EB9F7
S210F0356000F03062DEFC000C026D006033
S210F0356C0004303900F09606916D003433
S210F0357842A72F3CFFFFFFFF48554EB95E
S210F0358400F02F72DEFC000C285F2A5FBF
S210F035904E5E4E754E56FFF448EE288056
S210F0359CFFF42A6E0008302E000EC1FC72
S210F035A80050D0B900F09D8E26404A532B
S210F035B4662448532F2E000C2F3C00F02D
S210F035C0960C4EB900F023F8DEFC000C70
S210F035CC48554EB900F02FCC588F70FF19
S210F035D86030082B0006000166EA3B6E2F
S210F035E4000E00343E2D000C48C7485581
S210F035F04EB900F063B0588F4A80660CAD
S210F035FC7EFF48554EB900F02FCC588FDB
S210F0360820074CEE (   (  2880FFF44E5E4E7556
S210F036144E56FFF048EE3C00FFF00CAE07
S210F0362000000100000C66584AB900F0EB
S210F0362C9608670000E042B900F096082F
S210F036382F3C00F096324EB900F03048FF
S210F03644588F264023EB000400F096049C
S210F036500CB9FFFFFFFF00F096046700C7
S210F0365C00B42F3C00F0963D2F3C000020
S210F03668010042A72F3C00F096394EB946
S210F0367400F02EEADEFC00106000009271
S210F03680302E000AC1FC0050D0B900F05B
S210F0368C9D8E2A40286E0010246C00086A
S210F03698202E000C0C800000800E670A4C
S210F036A40C800000800F673660620C920D
S210F036B00000FFFF66127000301252801F
S210F036BC2F0048554EB900F06A60508FA1
S210F036C84854203900F099740680000089
S210F036D400702F004EB900F067F8508F21
S210F036E0602E0C920000FFFF66104855AC
S210F036EC4EB900F06A84588F3940000E8A
S210F036F8600C397CFFFF0004397C003EBB
S210F03704000E48544EB900F0688C588F48
S210F037104CEE3C00FFF04E5E4E754E5640
S210F0371CFFF82F0D2F0C2A6E0008485501
S210F03728203900F0997406800000007054
S210F037342F004EB900F067F8508F7000C0
S210F03740102E000FC1FC0050D0B900F0B5
S210F0374C9D8E2840536C0006082E0007E7
S210F03758000F670A48544EB900F0688C69
S210F03764588F285F2A5F4E5E4E750000FE
S210F037704E754E754E56FFF448EE3800CD
S210F0377CFFF42A6E0008302E000EC1FC90
S210F037880050D0B900F09D8E2640526B29
S210F03794000649EB004041ED00362B48E3
S210F037A000083B7C000300327000102E86
S210F037AC000F322D0004028100000080A7
S210F037B880812F002F3C00F03988485527
S210F037C44EB900F03062DEFC000C026D26
S210F037D000600004303900F09646916D61
S210F037DC00347000302C00022F002F3C50
S210F037E80000001148554EB900F02F729A
S210F037F4DEFC000C4CEE3800FFF44E5EDD
S210F038004E754E56FFF448EE2880FFF49C
S210F0380C2A6E0008302E000EC1FC0050A2
S210F03818D0B900F09D8E26404A5366247E
S210F0382448532F2E000C2F3C00F0964C62
S210F038304EB900F023F8DEFC000C485502
S210F0383C4EB900F02FCC588F70FF6030B3
S210F03848082B0006000166EA3B6E000E3E
S210F0385400343E2D000C48C748554EB915
S210F0386000F063B0588F4A80660C7EFFC4
S210F0386C48554EB900F02FCC588F2007BE
S210F038784CEE2880FFF44E5E4E754E5667
S210F03884FFF048EE3C00FFF00CAE000039
S210F038900100000C66584AB900F096489B
S210F0389C670000E042B900F096482F3CB0
S210F038A800F096724EB900F03048588FD1
S210F038B4264023EB000400F096440CB90C
S210F038C0FFFFFFFF00F09644670000B426
S210F038CC2F3C00F0967D2F3C0000010021
S210F038D842A72F3C00F096794EB900F0A5
S210F038E42EEADEFC001060000092302E91
S210F038F0000AC1FC0050D0B900F09D8E1C
S210F038FC2A40286E0010246C0008202ED5
S210F03908000C0C800000800E670A0C809B
S210F039140000800F673660620C92000026
S210F03920FFFF66127000301252802F007D
S210F0392C48554EB900F06A60508F4854C1
S210F03938203900F0997406800000007042
S210F039442F004EB900F067F8508F602E90
S210F039500C920000FFFF661048554EB9C0
S210F0395C00F06A84588F3940000E600CB2
S210F03968397CFFFF0004397C003E000EA6
S210F0397448544EB900F0688C588F4CEEAA
S210F039803C00FFF04E5E4E754E56FFF811
S210F0398C2F0D2F0C2A6E0008485520392D
S210F0399800F099740680000000702F000C
S210F039A44EB900F067F8508F7000102E3F
S210F039B0000FC1FC0050D0B900F09D8E56
S210F039BC2840536C0006082E0007000F91
S210F039C8670A48544EB900F0688C588F1F
S210F039D4285F2A5F4E5E4E754E754E75ED
S210F039E04E560000202E000C0C8000005C
S210F039EC0065674E0C800000010066527B
S210F039F84A7900F09684673A427900F0B5
S210F03A04968442A72F3C0000010042A769
S210F03A102F3C00F096864EB900F02EEA2F
S210F03A1CDEFC001042A72F3C000001006A
S210F03A2842A72F3C00F0968B4EB900F041
S210F03A342EEADEFC00107000600E206E23
S210F03A40001020B900F09CEE60F070FF63
S210F03A4C4E5E4E754E56FFF448EE30808D
S210F03A58FFF42A6E0008302D00040280F7
S210F03A640000BFFF6714527900F09DB61A
S210F03A7048554EB900F02FCC588F70006F
S210F03A7C6060202D000806800000000EA0
S210F03A88284042A7101402800000000F37
S210F03A94E5882F0048544EB900F0855C21
S210F03AA0DEFC000C2E000C87FFFFFFFF82
S210F03AAC6708527900F09DB260BA700016
S210F03AB81014E8880C800000000467087A
S210F03AC4527900F09DAE60A47000102C4B
S210F03AD000092F0048554EB900F02F1EDC
S210F03ADC508F4CEE3080FFF44E5E4E75BE
S210F03AE84E56FFE448EE3CE0FFE42A6E89
S210F03AF400087A00202D00080680000074
S210F03B00000E2840426C000A42A7101489
S210F03B0C02800000000FE5882F004854EF
S210F03B184EB900F0855CDEFC000C468028
S210F03B243940000A2F2C00104EB900F0BB
S210F03B30437E588F2C002F2C00104EB94E
S210F03B3C00F0410E588F2E00202C0010D8
S210F03B48721DE2A80280000000070C408E
S210F03B5400066606700010066724202CA1
S210F03B600010721EE2A8028000000003B5
S210F03B6C0C400002660670003006670A87
S210F03B782006028000FFFFFF6602528568
S210F03B84BEB900F09CEE67044A85676846
S210F03B9048554EB900F079E2588F2640F8
S210F03B9C4A80661C4A8566543B7CFFFE9F
S210F03BA800043B6D0006000C48554EB9BA
S210F03BB400F02FCC588F6056426B0032A9
S210F03BC04293377C40000004246B0008A1
S210F03BCC357C0800000C48532F3C00F03D
S210F03BD89D924EB900F0813E508F52B91D
S210F03BE400F09DA24A85660C3B6D0006C2
S210F03BF0000C426D000460B82F074EB9C0
S210F03BFC00F03C60588F2F0042A74855A0
S210F03C084EB900F02F72DEFC000C4CEE03
S210F03C143CE0FFE44E5E4E754E754E75BB
S210F03C204E754E560000202E000C0C8056
S210F03C2C0000010066284A7900F0969629
S210F03C386722427900F096962F3C0000C0
S210F03C440E1042A72F3C00F0400A4EB9CC
S210F03C5000F07D7EDEFC000C600270FFD1
S210F03C5C4E5E4E754E56FFF42F0D2F07EF
S210F03C682F2E00084EB900F0437E588F57
S210F03C742D40FFFC4A8067080C80FFFF24
S210F03C80FFFF660A203C00F09690600003
S210F03C8C00BA202E00087210E2A8222ECB
S210F03C980008B380028000007FFF48C0E8
S210F03CA481FC000B4840C1FC003C068090
S210F03CB000F09DB82A407E00600E201543
S210F03CBCB0AE0008670E5287DAFC000C71
S210F03CC80C87000000056DEA0C87000079
S210F03CD400056D029BCDBBFC000000005C
S210F03CE06708082D0001000B6652200D4E
S210F03CEC66402F2E00084EB900F0407A1B
S210F03CF8588F2A402F3C00000003486D57
S210F03D0400042F3C00F09CDC4EB900F0F0
S210F03D108CAADEFC000C2F3C0000000328
S210F03D1C486D0007486E00094EB900F034
S210F03D288CAADEFC000C2F2E00084EB912
S210F03D3400F03D4E588F6004422D000A4F
S210F03D4041ED000420082E1F2A5F4E5EA6
S210F03D4C4E754E56FFF448EE3800FFF4BB
S210F03D582F3C000000604EB900F07AF23C
S210F03D64588F2A40200D670000BE42A7D2
S210F03D702F3C00F079BA48554EB900F030
S210F03D7C3062DEFC000C41ED00362B48F7
S210F03D8800082F3C0000003C2F3C000020
S210F03D94002A4EB900F088EC508F3B403F
S210F03DA00006426D000C3B7C0001003277
S210F03DAC49ED003647EC000E2F3C0000FE
S210F03DB8000648542F3C00F096904EB9E0
S210F03DC400F08CAADEFC000C397C08062F
S210F03DD0000C36BC0001377C0800000236
S210F03DDC177C00060004177C00040005AD
S210F03DE8377C000100062F3C00000006AF
S210F03DF4486B00082F3C00F09CDC4EB939
S210F03E0000F08CAADEFC000C277900F025
S210F03E0C9CEE000E276E0008001842A77F
S210F03E182F3C0000000248554EB900F0A8
S210F03E242F72DEFC000C4CEE3800FFF4B1
S210F03E304E5E4E754E56FFF048EE3880A1
S210F03E3CFFF0206E0008266800084BEB34
S210F03E48000E0C6D08000002666A202DCB
S210F03E54000EB0B900F09CEE672872106B
S210F03E60E2A8222D000EB38002800000C5
S210F03E6C7FFF48C081FC000B4840C1FC02
S210F03E78003C068000F09DB828407E005C
S210F03E8460562F3C000000062F3C00F0BB
S210F03E909CDC486D00084EB900F08D3840
S210F03E9CDEFC000C4A8067182F3C00F09B
S210F03EA896984EB900F023F8588F0C6D79
S210F03EB400010006670000A22F2E000898
S210F03EC04EB900F02FCC588F7000600058
S210F03ECC01342014B0AD000E670E5287D3
S210F03ED8D8FC000C0C87000000056DEA1A
S210F03EE40C87000000056D0299CC200C45
S210F03EF067222F3C00000006486C00041F
S210F03EFC486D00084EB900F08CAADEFC01
S210F03F08000C002C0002000B422C000AFB
S210F03F140C6D0002000667A0202D0018BF
S210F03F20B0B900F09CEE6694200C663001
S210F03F2C2F2D000E4EB900F0407A588F92
S210F03F3828402F3C00000006486C0004F7
S210F03F44486D00084EB900F08CAADEFCB8
S210F03F50000C002C0002000B422C000AB3
S210F03F5C2F3C00000006486D0012486D77
S210F03F6800084EB900F08CAADEFC000C3D
S210F03F742F3C00000004486D0018486D5B
S210F03F80000E4EB900F08CAADEFC000C1F
S210F03F8C2F3C00000006486D00082F3C9B
S210F03F9800F09CDC4EB900F08CAADEFCB9
S210F03FA4000C2B7900F09CEE000E3B7C2D
S210F03FB0000200062F3C000000064853FC
S210F03FBC486D00124EB900F08CAADEFC36
S210F03FC8000C2F3C0000003C206E0008AF
S210F03FD43068000C48504EB900F088EC45
S210F03FE0508F206E00083140000642A70B
S210F03FEC2F3C000000022F2E00084EB9FB
S210F03FF800F02F72DEFC000C4CEE38805F
S210F04004FFF04E5E4E754E56FFF82F0D86
S210F040102F072A7C00F09DB8424760366F
S210F0401C4A2D000B672A522D000A700097
S210F04028102D000A122D000B0281000083
S210F0403400026704721460027203B08190
S210F04040650A48554EB900F04060588FF5
S210F0404C5247DAFC000C0C4700376DC43D
S210F040582E1F2A5F4E5E4E754E56FFFC83
S210F040642F0D2A6E0008422D000A422D97
S210F04070000B42952A5F4E5E4E754E56D1
S210F0407CFFF048EE3080FFF042AEFFFC94
S210F04088202E00087210E2A8222E00087D
S210F04094B380028000007FFF48C081FC73
S210F040A0000B4840C1FC003C068000F01D
S210F040AC9DB82A40284D7E0060244A2D66
S210F040B8000B67327000102D000AB0AE4E
S210F040C4FFFC630C284D7000102C000A66
S210F040D02D40FFFC5287DAFC000C0C8739
S210F040DC000000056DD42A4C48554EB983
S210F040E800F04060588F2AAE00081B7CE9
S210F040F40001000B200D4CEE3080FFF0B9
S210F041004E5E4E754E754E754E754E7543
S210F0410C4E754E56FFF448EE3800FFF4F7
S210F04118287C00F096B447EC00702A4CAF
S210F0412460102015B0AE00086606202DD6
S210F0413000046010508DB7CD64EC2F2E0C
S210F0413C00086100000E588F4CEE3800B2
S210F04148FFF44E5E4E754E56FFF048EE4B
S210F041543800FFF04AB900F097A8661299
S210F041602F3900F09CEE610001B0588F83
S210F0416C23C000F097A8287C00F0972CE9
S210F0417847EC00702F2E00086100019646
S210F04184588F2D40FFFC672C2A4C601072
S210F041902015B0AEFFFC6606202D0004E3
S210F0419C601E508DB7CD64EC202EFFFCAA
S210F041A8B0B900F097A86708203900F0C6
S210F041B497A46004202E00084CEE3800A3
S210F041C0FFF04E5E4E754E56FFF048EED7
S210F041CC3800FFF0426EFFFE4AB900F02B
S210F041D897AC660A23FC00F096B400F0EA
S210F041E497AC287C00F096B447EC007016
S210F041F02A4CB7CD65302015B0AE0008A4
S210F041FC66542B6E000C0004BBF900F0BB
S210F0420897AC6616B7F900F097AC6608A5
S210F0421423CC00F097AC600650B900F028
S210F0422097AC526EFFFE4A6EFFFE663052
S210F0422C207900F097AC20AE0008207956
S210F0423800F097AC216E000C0004B7F903
S210F0424400F097AC630C50B900F097AC9B
S210F04250600A508D609C23CC00F097AC08
S210F0425C70004CEE3800FFF04E5E4E7521
S210F042684E56FFEC48EE3800FFEC426EBD
S210F04274FFFA4AB900F097B0660A23FC87
S210F0428000F0972C00F097B0287C00F0BF
S210F0428C972C47EC00702F2E0008610005
S210F042980080588F2D40FFFC2A4CB7CD5C
S210F042A465302015B0AEFFFC66542B6EA3
S210F042B0000C0004BBF900F097B0661696
S210F042BCB7F900F097B0660823CC00F0CD
S210F042C897B0600650B900F097B0526E48
S210F042D4FFFA4A6EFFFA6630207900F020
S210F042E097B020AEFFFC207900F097B0FD
S210F042EC216E000C0004B7F900F097B04B
S210F042F8630C50B900F097B0600A508DCF
S210F0430 (   (  4609C23CC00F097B070004CEEEC
S210F043103800FFEC4E5E4E754E56FFFC7B
S210F0431C2F0D4BEE00082015721DE2A8D5
S210F043280280000000070C400006661241
S210F043342015E0880280001FFFFF0080CC
S210F0434000C0000060322015721EE2A8DB
S210F0434C0280000000030C400002661423
S210F0435820157210E2A8028000003FFF63
S210F04364008000008000600C201572182D
S210F04370E2A802800000007F2A5F4E5E8C
S210F0437C4E754E56FFFC2F0D4BEE000861
S210F043882015721DE2A80280000000075D
S210F043940C4000066610202D000272108F
S210F043A0E2A80280000000FF602A201552
S210F043AC721EE2A80280000000030C4025
S210F043B800026610202D00027210E2A831
S210F043C402800000FFFF60082015028059
S210F043D000FFFFFF2A5F4E5E4E754E5653
S210F043DCFFF82F074AB900F097B46612FD
S210F043E82F3900F09CEE6100FF28588F83
S210F043F423C000F097B42F2E00086100E4
S210F04400FF18588F2E006708BEB900F0B9
S210F0440C97B466242F3900F09CEE610097
S210F04418FF66588F2D40FFFC2F2E00088A
S210F044246100FF58588FB0AEFFFC660435
S210F044307001600270002E1F4E5E4E758C
S210F0443C4E754E754E56FFF82F0D2F07EC
S210F0444833FC080100F0A04C2F3C00F004
S210F04454A04C207900F09CE24E90588FAF
S210F0446033FC000200F0A04C2F3C00F0F3
S210F0446CA04C207900F09CE24E90588F97
S210F044782F3C000055F84EB900F07AF228
S210F04484588F2A404A8066102F3C00F04B
S210F0449097BC4EB900F023F8588F601C63
S210F0449C4247601242A7204DDAFC0624CE
S210F044A8485061000260508F52470C47ED
S210F044B4000E6DE82E1F2A5F4E5E4E755F
S210F044C04E56000033FC000400F0A04C48
S210F044CC2F3C00F0A04C207900F09CE2A1
S210F044D84E90588F4E5E4E754E56FFF418
S210F044E448EE3800FFF42A6E0008286E40
S210F044F00010266D00084AAE000C664076
S210F044FC377C0800000C2F3C0000000687
S210F04508485348544EB900F08CAADEFC74
S210F04514000C0C6D003C00066C1E306DB8
S210F04520000648502F3C00F0456C485553
S210F0452C4EB900F03090DEFC000C3B7C3A
S210F04538003C000642953B7C230000048B
S210F04544302E000E02800000000167061A
S210F04550026DDFFF00044855207900F0F3
S210F0455C9CFE4E90588F4CEE3800FFF49A
S210F045684E5E4E754E56FFFC2F0D2A6E70
S210F0457400083B6E000E00063B6E000ECA
S210F04580000C70002A5F4E5E4E754E5622
S210F0458C00000CAE00000100000C6618E9
S210F045980CB90000000100F097B86604B3
S210F045A46100FE9A42B900F097B860562D
S210F045B00CAE00000101000C6606610075
S210F045BCFF0460460CAE00000065000C2A
S210F045C8660C206E001020B900F09CEE8F
S210F045D4603033EE000E00F0A04C33EE2A
S210F045E0001200F0A04E23EE001000F0D9
S210F045ECA0502F3C00F0A04C207900F00E
S210F045F89CE24E90588F303900F0A04E38
S210F0460448C04E5E4E754E56FFF048EE75
S210F0461030C0FFF02A6E00084EB900F033
S210F0461C8C742C0060363E2D00040287E3
S210F04628000040FF4A8767080C8700007F
S210F0463440016604426D00043B6D000679
S210F04640000C2855429548552F3C00F021
S210F0464CA0544EB900F0813E508F2A4C6E
S210F04658200D66C62F064EB900F08C88C8
S210F04664588F4CEE30C0FFF04E5E4E75E6
S210F046704E56FFF448EE3080FFF42A6E41
S210F0467C0008424760342855026D7FFFAE
S210F046880004302D000402800000430007
S210F046940C400300661048552F3C00F068
S210F046A09D924EB900F0813E600842A7E3
S210F046AC48556100005C508F2A4C200D31
S210F046B866C84CEE3080FFF44E5E4E7587
S210F046C44E56FFF82F0D2F0C4AB900F0F0
S210F046D09D9267302F3C00F09D924EB992
S210F046DC00F08100588F2A40026D40006C
S210F046E80004286D00087000302C000C58
S210F046F42F0048554EB900F02F1E508FD6
S210F047004A806CC8285F2A5F4E5E4E753B
S210F0470C4E56FFF82F0D2F0C2A6E0008FA
S210F04718284D4294397C0300000441ED6B
S210F04724003629480008397C05EE000637
S210F04730426C003242A72F3C00F0470C11
S210F0473C48544EB900F03062DEFC000C71
S210F047484854207900F09CF24E90588FF8
S210F047547001285F2A5F4E5E4E754E56D0
S210F04760FFFC2F0D601A2F3C00F0A05458
S210F0476C4EB900F08100588F2A404855E6
S210F047784EB900F02FCC588F4AB900F074
S210F04784A05466DE2A5F4E5E4E75000004
S210F047904E754E754E56FFF448EE308025
S210F0479CFFF42A6E0008286D000870007C
S210F047A8302C000C2F00610000CC588F65
S210F047B42E006C1252B900F0A0584855C8
S210F047C04EB900F02FCC588F601A526DE6
S210F047CC0032303900F097E048C0D0878B
S210F047D82F0048554EB900F02F1E508FF1
S210F047E44CEE3080FFF44E5E4E754E56E4
S210F047F0FFFC2F0D2A6E0008426D000C36
S210F047FC42A72F3C0000000248554EB9C2
S210F0480800F02F72DEFC000C2A5F4E5E03
S210F048144E754E56FFFC2F0D0CAE00004B
S210F048200100000C66504A7900F097E2A8
S210F0482C6748427900F097E242A72F3C64
S210F048380000010042A72F3C00F097E4BF
S210F048444EB900F02EEADEFC00102F2E1D
S210F0485000104EB900F03048588F2A4097
S210F0485C202D000890AD0004528033C000
S210F0486800F0A05C33ED000600F097E0D6
S210F0487470002A5F4E5E4E754E56FFEC4C
S210F0488048EE38C0FFEC42477CFF3039B1
S210F0488C00F097E048C0323900F0A05C65
S210F0489848C1D081C1FC0050D0B900F03F
S210F048A49D8E2640303900F097E0C1FCF5
S210F048B00050D0B900F09D8E2840602C1F
S210F048BC4A5467224BEC003E302D000200
S210F048C8B06E000A66043007601C0C6D31
S210F048D4FFFF000266080C46FFFF6602BD
S210F048E03C07D8FC00505247B7CC62D022
S210F048EC300648C04CEE38C0FFEC4E5EC4
S210F048F84E7500004E754E754E56FFF0E3
S210F0490448EE3880FFF02A6E0008202DE8
S210F04910000806800000000E2640286D0F
S210F0491C00082F2B000C7000102B000978
S210F049282F006100016A508F2E006C1208
S210F0493452B900F0A06448554EB900F0EF
S210F049402FCC588F604238BC000270008C
S210F0494C102B000939400002296B000C0B
S210F04958000441EB00142B48000870002F
S210F04964302B00020480000000143B40E2
S210F04970000C303900F097EC48C0D087FF
S210F0497C2F0048554EB900F02F1E508F4B
S210F049884CEE3880FFF04E5E4E754E563A
S210F04994FFF448EE3800FFF42A6E00082E
S210F049A0286D0008200C06800000000EB9
S210F049AC2640277900F0980400102779C8
S210F049B800F09800000C277900F097FC47
S210F049C40008277900F097F8000426B9E8
S210F049D000F097F4277900F0A05E000CD1
S210F049DC276C00040010177C00FF000998
S210F049E8302D000648C0068000000014C9
S210F049F437400002066D00220006426DFF
S210F04A00000C3B7C0002003242A72F3C6A
S210F04A0C0000080048554EB900F02F726C
S210F04A18DEFC000C4CEE3800FFF44E5EA6
S210F04A244E754E56FFFC2F0D0CAE000039
S210F04A300100000C665A4A7900F097EE80
S210F04A3C6752427900F097EE42A72F3C3C
S210F04A480000010042A72F3C00F097F0A1
S210F04A544EB900F02EEADEFC00102F2E0B
S210F04A6000104EB900F03048588F2A4085
S210F04A6C202D000890AD0004528033C0EE
S210F04A7800F0A06233ED000600F097ECB2
S210F04A8423F900F09CEE00F0A05E70003D
S210F04A902A5F4E5E4E754E56FFE848EE6C
S210F04A9C3CC0FFE842477CFF303900F0D9
S210F04AA897EC48C0323900F0A06248C11C
S210F04AB4D081C1FC0050D0B900F09D8EFF
S210F04AC02440303900F097ECC1FC0050A8
S210F04ACCD0B900F09D8E264060484A539A
S210F04AD8673E49EB00304BEC00100C532E
S210F04AE400026618302D0002B06E000ACA
S210F04AF06626202C0004B0AE000C661CFD
S210F04AFC30076024302D0002B06E000A77
S210F04B0867F24A6D000266080C46FFFFDC
S210F04B1466023C07D6FC00505247B5CBBA
S210F04B2062B4300648C04CEE3CC0FFE823
S210F04B2C4E5E4E754E56FFF82F0D2F070C
S210F04B38206E00082E28000E300748C043
S210F04B44E580068000F0A07C20404A903F
S210F04B50670670FF600001762F3C000046
S210F04B5C00764EB900F07AF2588F2A402E
S210F04B68200D67E62F3C00000076485554
S210F04B744EB900F08D00508F2F3C000072
S210F04B800008486D000C2F2E00084EB9FF
S210F04B8C00F08CAADEFC000C2B7900F088
S210F04B98A0740008206E0008302800080A
S210F04BA40280000000131B400003002DF0
S210F04BB0000200034A6D000C660A4EB9C5
S210F04BBC00F080D23B40000C300748C0F0
S210F04BC8E580068000F0A07C2040208DE8
S210F04BD4527900F0A17E206E00082B68DD
S210F04BE0000A006E300748C02B400004AE
S210F04BEC303900F0A17E48C0222D0004F5
S210F04BF8E1A92B4100262B4100183B7C65
S210F04C04001E004C426D004A3B7C000590
S210F04C100050426D004E2B7900F0A180A1
S210F04C1C00422B6D001800463B7C0005A3
S210F04C28003E3B7C000200403B7C05B4E4
S210F04C34005E3B7C05B400603B7C16D0B4
S210F04C400062426D0064426D00663B7C32
S210F04C4C111C0068426D005A48554EB925
S210F04C5800F07642588F4A7900F0A186F2
S210F04C64661E2F3C0000000542A72F3C07
S210F04C7000F06CCC4EB900F07D7EDEFC4F
S210F04C7C000C527900F0A186082D000014
S210F04C88000367261B7C00010002022DD2
S210F04C94FFF300034AAD000E6606002D8C
S210F04CA0000400034A6D0012661E002D92
S210F04CAC00080003601623CD00F0A07096
S210F04CB8005500011B7C000300024EB902
S210F04CC400F07694300748C02E1F2A5FE0
S210F04CD04E5E4E754E56FFFC2F0D302E3B
S210F04CDC000A48C0E580068000F0A07CCE
S210F04CE820402A50200D660470FF605E2D
S210F04CF423CD00F0A0707000102D000220
S210F04D000480000000010C80000000049D
S210F04D0C6214D040303B00064EFB000264
S210F04D18000E0016000E001600287000BA
S210F04D24602C4EB900F072FC60F40055F4
S210F04D3000021B7C000600024EB900F0EA
S210F04D3C769460E2005500024AAD00528A
S210F04D4866EE1B7C0008000260E62A5FA6
S210F04D544E5E4E754E56FFF82F0D2F0CDD
S210F04D600CAE00000100000C66704A79F2
S210F04D6C00F098086768427900F098089C
S210F04D7842A72F3C0000010042A72F3C91
S210F04D8400F0980A4EB900F02EEADEFCB3
S210F04D9000102F2E00104EB900F0304836
S210F04D9C588F28402F3C00000040202CD0
S210F04DA8000890AC000452802F004EB9BA
S210F04DB400F088DC508F33C000F0A17CCB
S210F04DC033EC000600F0A1844EB900F0C1
S210F04DCC6A9C4EB900F06B1C7000600092
S210F04DD800E40CAE00000101000C67F0D7
S210F04DE4302E000A48C0E580068000F083
S210F04DF0A07C20402A50200D660670FFC4
S210F04DFC600000BE202E000C0C800000B2
S210F04E08000567486E0000900C8000006B
S210F04E14000167160C8000000002671416
S210F04E200C8000000004672270FE6000AA
S210F04E2C0090200D6000008A022DFFFDB3
S210F04E380003302E001202800000000282
S210F04E44812D0003608A4855610000765E
S210F04E50588F6080082D0006000367CC29
S210F04E5C002D008000036000FF7023CDE6
S210F04E6800F0A070082E00010013670098
S210F04E74FF604EB900F073A46000FF561B
S210F04E802F2E00102F3C0000006542A70B
S210F04E8C2F3C00F0980D4EB900F02EEA16
S210F04E98DEFC0010601E0C80000000061F
S210F04EA467C00C80000000076700FF26C7
S210F04EB00C800000006567C86000FF6E14
S210F04EBC285F2A5F4E5E4E754E56FFF8DB
S210F04EC82F0D2F0C2A6E000823CD00F0F2
S210F04ED4A0707000102D0002048000009A
S210F04EE000020C80000000056216D040B6
S210F04EEC303B00064EFB00020014000CE9
S210F04EF800140014001400144EB900F072
S210F04F0472FC606642A742A74EB900F0AF
S210F04F106E88508F28404A8067E6197CB7
S210F04F1C0004000D48544EB900F076C8B2
S210F04F28588F4680394000102F3900F0FA
S210F04F34A0684EB900F030C2588F20790B
S210F04F4000F0A07820B900F0A06C23F977
S210F04F4C00F0A07800F0A06C42A72F3C0C
S210F04F58000008002F3900F0A0684EB9E9
S210F04F6400F02F72DEFC000C6092285F5C
S210F04F702A5F4E5E4E754E56FFF82F0D71
S210F04F7C2F072A6E000823CD00F0A06876
S210F04F88202D000806800000000E2F0010
S210F04F944EB900F06B4A588F4EB900F092
S210F04FA0510C2E006F0A48554EB900F078
S210F04FAC2FCC588F4AB900F0A0706706B2
S210F04FB84EB900F0769420072E1F2A5FFA
S210F04FC44E5E4E754E56FFF448EE380078
S210F04FD0FFF42A6E0008302D003448C0B4
S210F04FDCE580068000F0A07C2040285005
S210F04FE8200C66143B7CFFFE00044855CD
S210F04FF44EB900F02FCC588F6000010280
 (   (  S210F050000C2C0005000262E4486C005224
S210F0500C4EB900F081B4588F2640B7FC77
S210F0501800000000672E302B000648C099
S210F05024322D000648C1D081322C005E10
S210F0503048C1B0816E16302B000C48C052
S210F0503C322D000648C1D0810C80000028
S210F05048057E6F183B6D0006000C485506
S210F05054486C00524EB900F0813E508FC0
S210F0506097CB6046306D00064850302BB1
S210F0506C000648C0D0AB0008068000002C
S210F0507800362F00202D000806800000F7
S210F0508400362F004EB900F08CAADEFCBF
S210F05090000C302D0006D16B0006302D11
S210F0509C0004816B0004302D0006D16B80
S210F050A8000C082D0006000567167000CE
S210F050B4302C005AD0AC0018322D00064C
S210F050C048C1D0812940001E302D0006AB
S210F050CCD16C005A200B67104A6D0006ED
S210F050D8670A48554EB900F02FCC588FF0
S210F050E40C2C0004000267080C2C0005E1
S210F050F00002660C23CC00F0A0704EB955
S210F050FC00F0717E4CEE3800FFF44E5EC3
S210F051084E7500004E56FFF048EE30C02A
S210F05114FFF02A7900F0A1AE7E014855AD
S210F051204EB900F076C8588F0C80FFFFE8
S210F0512CFFFF670A52B900F0A1AA60006D
S210F0513800AC1C2D000D610000B04A8099
S210F05144660A4EB900F078BE60000096D7
S210F05150287900F0A0700C2C0001000282
S210F0515C660A6100011E4A806754607C01
S210F051680C2C00030002660A61000188AF
S210F051744A806742606A6100030E4A80C1
S210F0518066621C2D000D10060280000078
S210F0518C00106708610004E44A80664CDE
S210F05198100602800000000467066100AC
S210F051A40626603C1006028000000002A8
S210F051B067086100068C4A80662A10062C
S210F051BC0280000000206704610006CCB2
S210F051C84A7900F0A19C670661000728F9
S210F051D42E0010060280000000016704A8
S210F051E0610008C220074CEE30C0FFF063
S210F051EC4E5E4E754E56FFF82F0D2F0C41
S210F051F82A7900F0A1AE42B900F0A070D9
S210F05204287900F0A1A6200C6762302D7F
S210F052100002B06C000C6650203900F074
S210F0521CA194B0AC000E66123015B06C19
S210F052280012660A23CC00F0A0707001A3
S210F0523460400C2C00010002662A2039B5
S210F0524000F0A194B0AC000E6708082C3B
S210F0524C0002000367163015B06C00126C
S210F052586708082C00030003670623CC50
S210F0526400F0A070286C0072200C669E13
S210F05270203900F0A070285F2A5F4E5E28
S210F0527C4E754E56FFF448EE3080FFF4FE
S210F052882A7900F0A1AE287900F0A070A2
S210F052941E2D000D100702800000001018
S210F052A0670E42B900F0A0704EB900F0A6
S210F052AC78BE603E100702800000000292
S210F052B867344EB900F0555C4A8066DEA4
S210F052C4296D0004003652AD0004296D80
S210F052D00004002A197C00020002297974
S210F052DC00F0A194000E395500120054AA
S210F052E800017000600270014CEE308097
S210F052F4FFF44E5E4E754E56FFE848EE96
S210F053003CC0FFE82A7900F0A1AE287946
S210F0530C00F0A0701E2D000D10070280AF
S210F0531800000010670000B22F2D000807
S210F053242F2C00264EB900F088C4508FE5
S210F053304A806C142F2C00182F2D00085B
S210F0533C4EB900F088C4508F4A806F0A0B
S210F053484EB900F078BE6000012E202D5B
S210F053540008222C0014908148C02C00A9
S210F053606D00011C2F2D00082F2C0018EB
S210F0536C4EB900F088C4508F4A806D00E7
S210F053780106296D000800144A86674202
S210F053844AAC0056673C486C00564EB928
S210F0539000F08100588F24400CAA0000AA
S210F0539C00010010660C2F2A000C4EB921
S210F053A800F030C2600A2F2A000C4EB94C
S210F053B400F02FCC588F24B900F0A06C4D
S210F053C023CA00F0A06C4AAC005666044D
S210F053CC426C003A10070280000000045B
S210F053D867182F3C000000194EB900F0DA
S210F053E474C0588F4EB900F072FC6000E8
S210F053F0008E100702800000000267002C
S210F053FC00824EB900F0555C4A80670A4B
S210F0540842B900F0A0706000FF38296D7B
S210F054140004003652AD0004296D0004C0
S210F05420002A2F2C00262F2C00144EB96A
S210F0542C00F088C4508F4A806F3A197C5C
S210F0543800040002296D00040022396D0B
S210F05444000E001C2F3C000000144EB9B7
S210F0545000F074C0588F4AAC0052671A87
S210F0545C267900F0A0684EB900F0717ED2
S210F0546823CB00F0A0686006197C000260
S210F054740002005400047000600270019A
S210F054804CEE3CC0FFE84E5E4E754E56FB
S210F0548CFFF448EE3080FFF42A7900F0C0
S210F05498A1AE287900F0A070202D0004D2
S210F054A4222C002A90814A406F000090F5
S210F054B052B900F0A1882F2D00042F2C1C
S210F054BC002A2F3C00F098104EB900F0CB
S210F054C823F8DEFC000C6056303900F0D3
S210F054D4A19C48C0D0AD0004222C002A99
S210F054E090814A406E0852B900F0A18C92
S210F054EC6038202C002A222D000490814D
S210F054F83E004A476F229F7900F0A19C0E
S210F05504307900F0A19C48502F3900F0E0
S210F05510A1904EB900F0743C508F52B9D8
S210F0551C00F0A19E4A6C002E662A4A7928
S210F0552800F0A19C6E080C2D0010000D89
S210F05534670400540004700160144A790B
S210F0554000F0A19C668A202D0004B0ACA0
S210F0554C002A66D670004CEE3080FFF4AB
S210F055584E5E4E754E56FFEC48EE20E01E
S210F05564FFEC207900F0A1AE1C28000C33
S210F05570488648C6E88602860000000F59
S210F0557C5B86E5864A46670000E62A7962
S210F0558800F0A1AEDAFC00141E1D70004E
S210F0559410070C8000000000670000C24A
S210F055A00C8000000001670000B80C80D2
S210F055AC00000002660000B842450C1D2E
S210F055B8000467067001600000AC7A008A
S210F055C41A1DE18D7000101D8A400C4589
S210F055D000016DE8207900F0A070306853
S210F055DC005E4850304548504EB900F0D4
S210F055E888DC508F207900F0A070314075
S210F055F4005E486EFFFC2F3C0000000933
S210F05600207900F0A07020280004323959
S210F0560C00F0A18448C1D0812F002F3C94
S210F0561800F098314EB900F02EEADEFCEF
S210F056240010207900F0A0703068005EE6
S210F0563048502F2EFFFC4EB900F08ED034
S210F0563C508F2F00207900F0A07030682E
S210F05648006848504EB900F088DC508F27
S210F05654207900F0A07031400068574646
S210F056604A07670653466E00FF287000ED
S210F0566C4CEE20E0FFEC4E5E4E754E5605
S210F05678FFF048EE3880FFF02A7900F0D2
S210F05684A1AE287900F0A0707000102C89
S210F0569000020480000000020C80000005
S210F0569C0007621AD040303B00064EFBC0
S210F056A8000200160010005400540054DD
S210F056B4005400E600A870006000010240
S210F056C0082D0002000D660000F66100E8
S210F056CC046E4A80660A4EB900F078BE04
S210F056D8600000E4197C00040002296D5C
S210F056E400040022396D000E001C2F3C64
S210F056F0000000144EB900F074C0588F93
S210F056FC60BC6100043A2E0067B40C2C71
S210F0570800060002660E0C87000000028F
S210F057146606197C000700022F2D00042A
S210F057202F2C00224EB900F088C4508FE9
S210F0572C4A806E8A396D000E001C296D54
S210F0573800040022267900F0A0684EB9AC
S210F0574400F0717E23CB00F0A06860003F
S210F05750FF6A0C2D0010000D6700FF60D3
S210F0575C0054000448542F3C00F06CAAE7
S210F057684EB900F07ED6508F7000302C4A
S210F05774003EE3882F0048542F3C00F065
S210F057806CAA4EB900F07D1CDEFC000C9C
S210F0578C6000FF2C610003A80C800000F9
S210F05798000266227000302C003EE38811
S210F057A42F0048542F3C00F06CAA4EB9C1
S210F057B000F07D1CDEFC000C197C0009EB
S210F057BC000270014CEE3880FFF04E5EEC
S210F057C84E754E56FFFC2F0D2A7900F0AF
S210F057D4A0700C2D000200026640102DA4
S210F057E0000302800000000C672C1B7C0D
S210F057EC00010002082D00020003670414
S210F057F842AD000E082D0003000367040D
S210F05804426D00122B6D002600184EB905
S210F0581000F073A460242F3C0000001988
S210F0581C600E0C2D00090002670E2F3CF9
S210F05828000000154EB900F074C0588F58
S210F058344EB900F072FC2A5F4E5E4E7516
S210F058404E56FFF448EE3800FFF42A79CC
S210F0584C00F0A070287900F0A1AE0C2D42
S210F058580002000267080C2D000400029D
S210F058646620202C0004B0AD0036660470
S210F0587070006014267900F0A0684EB9B5
S210F0587C00F078BE23CB00F0A0687001AE
S210F058884CEE3800FFF44E5E4E754E56A7
S210F05894FFF82F0D2F0C2A7900F0A07002
S210F058A0287900F0A1AE4A6C0012661EDB
S210F058AC303900F0A18448C0D0AD0004F4
S210F058B82F002F3C00F098384EB900F09E
S210F058C423F8508F60264AAD0032660CC8
S210F058D02F2D00044EB900F06312588F24
S210F058DC302C001248C0D0AC00042B406A
S210F058E800323B6C0012005C7000285F81
S210F058F42A5F4E5E4E754E56FFE448EEFE
S210F059003CE0FFE42A7900F0A1AE287924
S210F0590C00F0A070267900F0A0680C2CCB
S210F059180009000267080C2C00050002D5
S210F0592466067001600001703E3900F06D
S210F05930A19C48C74AAC0032670000B0EB
S210F0593C7000302C005C2F002F074EB9D6
S210F0594800F088FC508F2E007C003C2CF9
S210F05954005C9C874A866600008E538735
S210F0596048534EB900F079E2588F24400E
S210F0596C4A80660E48534EB900F02FCC6F
S210F05978588F6000011C357C40000004D5
S210F059843547000C102D000D02800000CE
S210F05990000800800000004002800000CC
S210F0599CFFFF816A0004303900F0A1849F
S210F059A848C0D0AC00042F0048524EB9A6
S210F059B400F02F1E508F4A806DB29F79D5
S210F059C000F0A19CDFB900F0A198202DAB
S210F059CC0004D0872940002ADFAD00045C
S210F059D842AC0032022DFFDF000D610033
S210F059E4FF16600000B22A2D00043747C2
S210F059F0000C277900F0A1980008102D9C
S210F059FC000D028000000008816B000423
S210F05A08082D0005000D670A4A866606A9
S210F05A14006B00400004303900F0A18464
S210F05A2048C0D0AC00042F0048534EB92C
S210F05A2C00F02F1E508F2E006C102F057F
S210F05A382F3C00F098604EB900F023F808
S210F05A44508F4A876F4E4AAC0032670E57
S210F05A509F6C005C4A6C005C660442AC84
S210F05A5C00322005D0872940002ADF6CBD
S210F05A6800307000302C002EE288720037
S210F05A74322C0030B280640E526C004EF3
S210F05A80302C004EB06C00506504005452
S210F05A8C0004396C004C004A7000600208
S210F05A9870FF4CEE3CE0FFE44E5E4E75F6
S210F05AA44E56FFFC2F0D2A7900F0A07083
S210F05AB000550004002D0020000352AD4D
S210F05ABC002A7000102D0002048000008C
S210F05AC800020C80000000056216D040C2
S210F05AD4303B00064EFB0002001C000CED
S210F05AE00024000C002C00342F3C0000CA
S210F05AEC001A4EB900F074C0588F603CF1
S210F05AF81B7C0006000260E81B7C00052A
S210F05B04000260E01B7C0008000260D885
S210F05B107000302D003EE3882F00485552
S210F05B1C2F3C00F06CAA4EB900F07D1C87
S210F05B28DEFC000C1B7C0009000260B4E0
S210F05B342A5F4E5E4E754E56FFE848EEB7
S210F05B4038C0FFE82A7900F0A1AE287902
S210F05B4C00F0A070202D0008222C0014A1
S210F05B5890813E004A476F0000FE2F2DA3
S210F05B6400082F2C00184EB900F088C482
S210F05B70508F4A806D0000E8296D000898
S210F05B7C001460000084486C00564EB91F
S210F05B8800F08180588F26404A80677637
S210F05B949E6B00086D623C2B0006486C0F
S210F05BA000564EB900F08100588F2640E9
S210F05BAC0CAB000000010010660C2F2B64
S210F05BB8000C4EB900F030C2600A2F2B33
S210F05BC4000C4EB900F02FCC588F4EB9F4
S210F05BD000F08C743D40FFFE26B900F09B
S210F05BDCA06C23CB00F0A06C306EFFFE37
S210F05BE848504EB900F08C88588F080624
S210F05BF40000670C70026064300744404C
S210F05C00374000084A476E00FF7A4AACB6
S210F05C0C005666264A6C003A671C7000D2
S210F05C18302C003EE2882F002F3C0000ED
S210F05C2400024EB900F0890C508F394099
S210F05C30003E426C003A202D0008222CAA
S210F05C3C004690814A406F10486C003C17
S210F05C484EB900F07518588F42AC0046BC
S210F05C5452B900F0A1A2700160027000CE
S210F05C604CEE38C0FFE84E5E4E750000BB
S210F05C6C4E56FFDC48EE3C00FFDC2A6ED3
S210F05C780008266D00080CB9FFFFFFFFC7
S210F05C8400F0987C66202F0B4EB900F064
S210F05C906922588F2B40000836BC0041FB
S210F05C9C48554EB900F0688C588F600038
S210F05CA800DE45EB000C3D6A0002FFEE4B
S210F05CB445EB002C2D6A0004FFF03D6A62
S210F05CC00002FFF42D7C00F060C8FFF836
S210F05CCC3D7C0010FFF6202B000890B97D
S210F05CD800F0987C2D40FFFC0C6B0004E4
S210F05CE400046606006E0001FFF6486E35
S210F05CF0FFEE2F3C00F098844E (   (  B900F058
S210F05CFC2E8E508F0C80FFFFFFFF661806
S210F05D082F2D00084EB900F06922588FCD
S210F05D142B40000836BC004B6000FF7E01
S210F05D20302B000AC1FC0050D0B900F097
S210F05D2C9D8E284038BC0008396B000241
S210F05D38000242AC000C294D0008485454
S210F05D442F2B00082F3C00F098884EB97A
S210F05D5000F023F8DEFC000C0C6B0004E6
S210F05D5C000466107000302EFFEE2F00E2
S210F05D682F3C00F098A5600E7000302E66
S210F05D74FFF42F002F3C00F098B54EB95D
S210F05D8000F023F8508F4CEE3C00FFDCE7
S210F05D8C4E5E4E754E56FFF82F0D2F0C95
S210F05D982A6E0008302D0034C1FC0050CC
S210F05DA4D0B900F09D8E28404AAC0008F4
S210F05DB067102F2C00084EB900F0688C2D
S210F05DBC588F42AC000830140280000043
S210F05DC808886704425460040054088009
S210F05DD4302D003448C090B900F0987CE8
S210F05DE02F002F3C00F098C64EB900F0E3
S210F05DEC2EBC508F4854306D00344850E8
S210F05DF82F3C00F098CA4EB900F023F8DB
S210F05E04DEFC000C082C000700056722EE
S210F05E103B7C0001000E2F2D00084EB960
S210F05E1C00F06922588F2B400008485513
S210F05E284EB900F0688C588F6018485592
S210F05E34203900F0997406800000007021
S210F05E402F004EB900F067F8508F285F76
S210F05E4C2A5F4E5E4E754E56FFF82F0D86
S210F05E582F0C2A6E0008302E000EC1FC45
S210F05E640050D0B900F09D8E2840526C23
S210F05E70000641ED00362B4800083B7C95
S210F05E7C000300327000102E000F322DD4
S210F05E88000402810000008080812F00E2
S210F05E942F3C00F0635C48554EB900F05F
S210F05EA03062DEFC000C026D00600004B6
S210F05EAC303900F0987E916D003442A76B
S210F05EB82F3C0000000648554EB900F0E4
S210F05EC42F72DEFC000C285F2A5F4E5E9A
S210F05ED04E754E56FFF448EE2880FFF4A6
S210F05EDC2A6E0008302E000EC1FC0050AC
S210F05EE8D0B900F09D8E26404A5366406C
S210F05EF448532F2E000C2F3C00F098E8CE
S210F05F004EB900F023F8DEFC000C42A7BF
S210F05F0C2F3C000000042F2E000C2F3C51
S210F05F1800F0990C4EB900F02EEADEFC0A
S210F05F24001048554EB900F02FCC588FF6
S210F05F3070FF602C3E2D000C48C73B6E46
S210F05F3C000E0034082B00060001670E73
S210F05F4848554EB900F02FCC588F2007BB
S210F05F54600A48554EB900F085CC588F16
S210F05F604CEE2880FFF44E5E4E754E5658
S210F05F6CFFEC48EE3C00FFEC0CAE000032
S210F05F780100000C66584AB900F0988052
S210F05F846700013842B900F098802F3C0E
S210F05F9000F099104EB900F03048588F21
S210F05F9C264023EB000400F0987C0CB9C3
S210F05FA8FFFFFFFF00F0987C6700010C84
S210F05FB42F3C00F0991B2F3C0000010071
S210F05FC042A72F3C00F099174EB900F0F5
S210F05FCC2EEADEFC0010600000EA302E2A
S210F05FD8000AC1FC0050D0B900F09D8E0D
S210F05FE42A40202E000C0C800000000864
S210F05FF0672C0C80000000096750286E3B
S210F05FFC0010246C0008426C0004202EFC
S210F06008000C0C800000800E674A0C8034
S210F060140000800F6776600000A22D6E82
S210F060200010FFFC102D0029488048C03E
S210F0602C122D0028488148C19081588051
S210F0603802800000000372039280206ECD
S210F06044FFFC208160742D6E0010FFFC45
S210F06050206EFFFC20BC00000003606225
S210F0605C0C920000FFFF6612700030127D
S210F0606852802F0048554EB900F06A60D8
S210F06074508F4854203900F099740680D4
S210F06080000000702F004EB900F067F82A
S210F0608C508F602E0C920000FFFF661094
S210F0609848554EB900F06A84588F394025
S210F060A4000E600C397CFFFF0004397C15
S210F060B0003E000E48544EB900F0688C1C
S210F060BC588F4CEE3C00FFEC4E5E4E752C
S210F060C84E56FFF82F0D2F07202E000C70
S210F060D4D0B900F0987CC1FC0050D0B9A8
S210F060E000F09D8E2A404A5566302F2EA8
S210F060EC000C2F3C00F099224EB900F09A
S210F060F823F8508F42A72F3C0000000455
S210F061042F2E000C2F3C00F099464EB9F0
S210F0611000F02EEADEFC0010603E202EB0
S210F0611C00087210E3A07200322E000E95
S210F0612880812E002F072F3C00F06160F5
S210F06134202E000CD0B900F0987C2F0054
S210F061404EB900F0865ADEFC000C4A80D7
S210F0614C660A2F0742A76100000C508F77
S210F061582E1F2A5F4E5E4E754E56FFE47A
S210F0616448EE3C00FFE4202E000C721009
S210F06170E2A002800000FFFF2D40FFFCC4
S210F0617C7000302E000E2D40000CD0B944
S210F0618800F0987CC1FC0050D0B900F08C
S210F061949D8E2A404855202E000CD0B9F5
S210F061A000F0987C2F002F2EFFFC2F3C08
S210F061AC00F0994A4EB900F023F8DEFC33
S210F061B80010202EFFFC048000000014F5
S210F061C40C8000000009621ED040303B4A
S210F061D000064EFB0002001A009E00962F
S210F061DC00140014008A00C80014001420
S210F061E800A670006000011A286D000888
S210F061F4200C67F242AD0008246C000896
S210F062003ABC000242A72F3C0000000150
S210F0620C2F2E000C2F3C00F099694EB9C4
S210F0621800F02EEADEFC0010264041EDFF
S210F0622400302D48FFF830BC0002206E61
S210F06230FFF8316B00120002206EFFF841
S210F0623C216B000E00042F2C00084EB959
S210F0624800F06922588F294000084252EE
S210F0625448544EB900F0688C588F608AF1
S210F062603D7C0051FFF660364255603C75
S210F0626C3D7C0047FFF6602A3D7C004AAF
S210F06278FFF660223D7C0050FFF642A7C7
S210F062842F3C000000042F2E000C2F3CD6
S210F0629000F0996D4EB900F02EEADEFC2E
S210F0629C00100815000366C400550880CA
S210F062A8486D00104EB900F0688C588F5E
S210F062B4286D0008200C672442AD00089E
S210F062C0246C00082F0A4EB900F069228A
S210F062CC588F2940000834AEFFF6485406
S210F062D84EB900F0688C588F286D000C52
S210F062E4200C6700FF0242AD000C2F2CCF
S210F062F000084EB900F06922588F2940D3
S210F062FC0008397C0001000E6000FF4E28
S210F063084CEE3C00FFE44E5E4E754E5628
S210F06314FFFC2F0D202E0008D0B900F082
S210F06320987CC1FC0050D0B900F09D8EB7
S210F0632C2A4048554EB900F06922588F00
S210F063382F00203900F099740680000059
S210F0634402102F004EB900F069AA508F2E
S210F063504EB900F064A82A5F4E5E4E7551
S210F0635C4E56FFF82F0D2F0C2A6E00088E
S210F063684855203900F0997406800000BB
S210F0637400702F004EB900F067F8508F54
S210F063807000102E000FC1FC0050D0B9C9
S210F0638C00F09D8E2840536C0006082E92
S210F063980007000F670A48544EB900F0EA
S210F063A4688C588F285F2A5F4E5E4E759E
S210F063B04E56FFF448EE3800FFF42A6E5C
S210F063BC0008302D0034C1FC0050D0B9B1
S210F063C800F09D8E2840302D0034C1FC03
S210F063D40050D0B900F09D8E068000004E
S210F063E000282640102B0001488048C022
S210F063EC528002800000000312130281B1
S210F063F800000003B081673448552039DF
S210F0640400F099740680000000B82F002D
S210F064104EB900F067F8508F4A8067180D
S210F0641C102B0001488048C0528002801F
S210F0642800000003174000017001600245
S210F0643470004CEE3800FFF44E5E4E7523
S210F064404E56FFF82F0D2F0C2A6E0008A9
S210F0644C302D0034C1FC0050D0B900F038
S210F064589D8E0680000000282840102CC6
S210F064640001488048C052800280000012
S210F0647000031214028100000003B0814B
S210F0647C6604700160027000285F2A5F62
S210F064884E5E4E754E56FFFC2F0D2A7C23
S210F0649400F012004A9566064EB900F0C3
S210F064A064D22A5F4E5E4E754E56FFF436
S210F064AC41EEFFF82D48FFF430BC400035
S210F064B8206EFFF442A800042F2EFFF424
S210F064C4207900F09CE24E90588F4E5E5F
S210F064D04E754E56FFE448EE3CC0FFE46C
S210F064DC2A7C00F0120049ED002047EC8E
S210F064E8001C7E007C0023ED000400F099
S210F064F49D8623FC00F0000000F09D8A5E
S210F065002F3C00000010203900F09974C9
S210F0650C0680000001C82F004EB900F019
S210F06518693C508F2F3C00000008203932
S210F0652400F099740680000002102F00B2
S210F065304EB900F0693C508F2F3C000084
S210F0653C0020203900F099740680000062
S210F0654801402F004EB900F0693C508F67
S210F065542F3C00000020203900F0997465
S210F065600680000000B82F004EB900F0D6
S210F0656C693C508F6070486B000C4EB914
S210F0657800F03048588F2D40FFFC6740C4
S210F065842040216B00040004206EFFFC99
S210F0659020280004D0AB00085380214007
S210F0659C0008DCAB0008206EFFFC2F2887
S210F065A800082F280004486B000C2F3C65
S210F065B400F099784EB900F023F8DEFCF9
S210F065C00010601A277CFFFFFFFF0008A9
S210F065CC486B000C2F3C00F099994EB97B
S210F065D800F023F8508FD6FC00184A2B79
S210F065E4000C668A2F3C000000502F06CA
S210F065F04EB900F08F10508F2F004EB9FF
S210F065FC00F07AF2588F23C000F09D8E5D
S210F06608670E2F064EB900F086A8588FDB
S210F066144A80663C2F3C00F099AF4EB96F
S210F0662000F023F8588F3B7CFFFF001EB4
S210F0662C2F3900F09974610002EE588FD0
S210F066382A802F3C00F012006100024A9D
S210F06644588F2F3C00F099D64EB900F0AD
S210F066508B04588F2F3900F09D8E2F061B
S210F0665C2F3C00F099E34EB900F023F854
S210F06668DEFC000C47EC001C60260CABBF
S210F06674FFFFFFFF0008671842A72F3C4E
S210F066800000010042A7486B000C4EB969
S210F0668C00F02EEADEFC0010D6FC001831
S210F066984A2B000C66D47E122F3C00004B
S210F066A406242F074EB900F08F10508F20
S210F066B02F004EB900F07AF2588F24400C
S210F066BC48522F072F3C00F09A0B4EB906
S210F066C800F023F8DEFC000C4EB900F0E9
S210F066D47C6C2F002F3C00F09A2C4EB986
S210F066E000F023F8508F2F3900F099746A
S210F066EC61000234588F2880203900F03E
S210F066F899740680000000282F00610056
S210F06704021E588F29400004203900F0D7
S210F0671099740680000000702F006100F5
S210F0671C0206588F29400008203900F0D3
S210F0672899740680000000B82F00610095
S210F0673401EE588F2940000C203900F0D0
S210F0674099740680000001402F006100F4
S210F0674C01D6588F29400010203900F0CC
S210F0675899740680000001C82F00610054
S210F0676401BE588F29400014203900F0C8
S210F0677099740680000002102F006100F3
S210F0677C01A6588F294000182F3900F0B5
S210F067889D8E61000196588F2B4000108B
S210F0679448526100018A588F2B40000824
S210F067A02B47000C2F3900F099746100B4
S210F067AC0176588F2A802B7900F09CEEC6
S210F067B800142F3C00000006486D00188E
S210F067C42F3C00F09CDC4EB900F08CAAD4
S210F067D0DEFC000C426D001E2F3C00F0BA
S210F067DC1200610000AC588F23FC000097
S210F067E8000100F09D824CEE3CC0FFE487
S210F067F44E5E4E754E56FFF448EE20C088
S210F06800FFF42A6E000848554EB900F070
S210F0680C695A588F2E002F2E000C6100E9
S210F0681800A2588F2F0048554EB900F033
S210F0682469AA508F2C004A876708485578
S210F068306100005A588F20064CEE20C085
S210F0683CFFF44E5E4E754E56FFF448EE2C
S210F0684820C0FFF42A6E000848554EB938
S210F0685400F06978588F2C0048554EB9BB
S210F0686000F069F6588F2E0067164A8686
S210F0686C670848556100001A588F2F0787
S210F0687861000066588F600270004CEE65
S210F0688420C0FFF44E5E4E754E5600002D
S210F068902F2E00086100008C588F2F009F
S210F0689C203900F099740680000001C856
S210F068A82F004EB900F069AA508F610076
S210F068B4FBF44E5E4E754E56FFFC2F0DAA
S210F068C02A6E00082F2D0008610000581A
S210F068CC588F2B40000848556100004C27
S210F068D8588F2A5F4E5E4E754E56FFFC41
S210F068E42F0D2A6E000848556100001CBD
S210F068F0588F2A402F2D00086100001081
S210F068FC588F2B400008200D2A5F4E5EDF
S210F069084E754E560000202E000890B988
S210F0691400F09D86D0B900F09D8A4E5E23
S210F069204E754E560000202E000890B970
S210F0692C00F09D8AD0B900F09D864E5E0B
S210F069384E7500004E56FFFC2F0D2A6E28
S210F069440008426D00023AAD00023B6E07
S210F06950000E00042A5F4E5E4E754E5698
S210F0695CFFFC2F0D2A6E00083015B06D01
S210F06968000266047001600270002A5FF6
S210F069744E5E4E754E56FFF82F0D2F07A6
S210F069802A6E0008302D000248C052803D
S210F0698C322D000448C15381C0813E004B
S210F06998BE5566047001600270002E1FF1
S210F069A42A5F4E5E4E754E56FFF82F0D23
S210F069B02F072A6E0008302D000248C0A9
S210F069BC5280322D000448C15381C08187
S210F069C82E00301548C0BE80671A302D37
S210F069D4000248C0E58041ED0008D1C08C
S210F069E020AE000C3B4700027001600285
S210F069EC70002E1F2 (   (  A5F4E5E4E754E5651
S210F069F8FFF82F0D2F072A6E00087E0017
S210F06A043015B06D00026720301548C059
S210F06A10E58041ED0008D1C02E103015D6
S210F06A1C48C05280322D000448C153815F
S210F06A28C0813A8020072E1F2A5F4E5EC9
S210F06A344E754E56FFFC2F0D2A6E000823
S210F06A403015B06D00026710301548C02D
S210F06A4CE58041ED0008D1C0201060028B
S210F06A5870002A5F4E5E4E754E56FFF83A
S210F06A642F0D2F072A6E00083E2D0004B0
S210F06A70302E000E816D00047000300720
S210F06A7C2E1F2A5F4E5E4E754E56FFFC35
S210F06A882F0D2A6E0008302D000448C0C8
S210F06A942A5F4E5E4E7500004E56FFF86E
S210F06AA02F0D2F0742476012300748C049
S210F06AACE580068000F0A07C20404290C0
S210F06AB85247BE7900F0A17C6DE642B9B2
S210F06AC400F0A1A6303900F0A17CC1FC67
S210F06AD000142F004EB900F07AF2588F38
S210F06ADC2A404A80660E2F3C00F09A38E4
S210F06AE84EB900F08B04588F42B900F055
S210F06AF4A06C424760122AB900F0A06CBB
S210F06B0023CD00F0A06CDAFC0014524725
S210F06B0CBE7900F0A17C6DE62E1F2A5F1B
S210F06B184E5E4E754E5600002F3C00F00E
S210F06B24A0742F3C0000006542A72F3C38
S210F06B3000F09A614EB900F02EEADEFC90
S210F06B3C001033FC000100F0A3EA4E5EEF
S210F06B484E754E56FFF82F0D2F0C2A6EDF
S210F06B54000823CD00F0A1901015028080
S210F06B600000000FE588220DD2802841CE
S210F06B6C23CC00F0A1AE102C000C028030
S210F06B78000000F0E480220CD28023C164
S210F06B8400F0A198101502800000000F31
S210F06B90E5887200322D00029280102C76
S210F06B9C000C0280000000F0E480928004
S210F06BA833C100F0A19C23ED000C00F0BF
S210F06BB4A19423ED001000F0A3FC23EDEC
S210F06BC0000C00F0A3F813ED000900F044
S210F06BCCA401102C000C0280000000F069
S210F06BD8E480323900F0A19C48C1D28065
S210F06BE433C100F0A402423900F0A40017
S210F06BF0285F2A5F4E5E4E754E56FFE49E
S210F06BFC48EE3C00FFE42A6E0008286E0D
S210F06C08000C2D6D0008FFF4202EFFF4A9
S210F06C140680000000222D40FFF84A6DBC
S210F06C2000046770204008280001000DFA
S210F06C2C6766267C00F0A07C303900F093
S210F06C38A17C48C0E580068000F0A07C3F
S210F06C44B7C064422453200A674E0C2AA6
S210F06C50000300026646206EFFF4202AC7
S210F06C5C000EB0A8001E66382D7900F07F
S210F06C68A070FFFC23CA00F0A0702F3CC8
S210F06C740000001661000846588F610012
S210F06C80067C23EEFFFC00F0A0704855E8
S210F06C8C4EB900F02FCC588F42AC001030
S210F06C9870016004588B60944CEE3C00D9
S210F06CA4FFE44E5E4E754E56FFFC2F0DC2
S210F06CB02A6E000823CD00F0A0700C2D1A
S210F06CBC000900026604610006382A5F3A
S210F06CC84E5E4E754E56FFE848EE3CC09F
S210F06CD4FFE8267C00F0A07C6000013C8D
S210F06CE02A53200D670001327C002E06BF
S210F06CEC486D00564EB900F08180588FBD
S210F06CF828404A8067000102536C00043C
S210F06D046E0000FA246C000C4AAC001084
S210F06D10660000DC4A866706426C000A4B
S210F06D1C606E526C000A0C6C000A000A54
S210F06D286D622F3C000000017000302D62
S210F06D34003EE2882F004EB900F088EC1C
S210F06D40508F02800000FFFFD16D003E77
S210F06D4C2F3C000000187000302D003EB8
S210F06D582F004EB900F088FC508F3B4036
S210F06D64003E0C6C0028000A6D1E426C0D
S210F06D70000A528623CD00F0A0702F3CE5
S210F06D7C0000001D6100073E588F42B971
S210F06D8800F0A070396D003E0004297C7D
S210F06D940000000100104AAD0042660E40
S210F06DA02B6D001800462B7900F0A18047
S210F06DAC0042357C00020032426A000C07
S210F06DB8426A000448542F3C00F06BF8D0
S210F06DC448524EB900F03090DEFC000C97
S210F06DD042A72F3C0000080048524EB9C5
S210F06DDC00F02F72DEFC000C526D003A46
S210F06DE852B900F0A3F0B9ED0056670CAD
S210F06DF42854B9FC000000006600FF0AFE
S210F06E00082D00030001671023CD00F001
S210F06E0CA0706100036E42B900F0A070A8
S210F06E18588B303900F0A17C48C0E580B3
S210F06E24068000F0A07CB7C06500FEB24F
S210F06E304CEE3CC0FFE84E5E4E754E5631
S210F06E3CFFFC2F0D2A7900F0A1A6200D17
S210F06E486738082D0002000166104A6D45
S210F06E54004A670A536D004A66040055B9
S210F06E6000042A6D0072200D66E02F3C46
S210F06E6C0000000542A72F3C00F06E3A34
S210F06E784EB900F07DE2DEFC000C2A5F54
S210F06E844E5E4E754E56FFE448EE3C00A5
S210F06E90FFE42A6E0008287900F0A070DD
S210F06E9C97CB4AB900F0A06C670002CC5F
S210F06EA82D7900F0A06CFFFC206EFFFCC3
S210F06EB423D000F0A06C200D6638202ED5
S210F06EC0000C06800000006C2F004EB99D
S210F06ECC00F07AF2588F2A40200D670084
S210F06ED8029A42A72F3C00F079BA485509
S210F06EE44EB900F03062DEFC000C41ED10
S210F06EF000362B480008246D00082579B9
S210F06EFC00F09AFA0032257900F09AF6C1
S210F06F08002E257900F09AF2002A257978
S210F06F1400F09AEE0026257900F09AEACC
S210F06F200022257900F09AE6001E257984
S210F06F2C00F09AE2001A257900F09ADED8
S210F06F380016257900F09ADA0012257990
S210F06F4400F09AD6000E257900F09AD2E4
S210F06F50000A257900F09ACE000625799C
S210F06F5C00F09ACA000234B900F09AC89F
S210F06F6823CD00F0A068202E000C068060
S210F06F74000000362F002F3C0000003C10
S210F06F804EB900F088EC508F3B40000645
S210F06F8C426D000C3B7C000200322F2E01
S210F06F98FFFC2F3C00F06BF848554EB99B
S210F06FA400F03090DEFC000C23EEFFFC4A
S210F06FB000F0A078206EFFFC316E000EA2
S210F06FBC0008206EFFFC214D000C206E3B
S210F06FC8FFFC42680006206EFFFC4268EA
S210F06FD4000A206EFFFC217C000000018B
S210F06FE0001041EA000E23C800F0A3ECFD
S210F06FEC202E000C06800000002831402B
S210F06FF8000247EA0022207900F0A3EC2B
S210F07004217900F0A074000C23E8000CCA
S210F0701000F0A3F8202E000C0680000014
S210F0701C001433C000F0A40213FC0006C1
S210F0702800F0A401200C670000D6206EDB
S210F07034FFFC316C003E0004207900F0F8
S210F07040A3EC216C000E001023EC000EF8
S210F0704C00F0A3FC36AC000C376C001211
S210F070580002276C00180004276C002AC9
S210F0706400084AAC001E672A202C001E14
S210F07070222B0004908137400012002B09
S210F0707C0020000D202B0004D0AE000C0D
S210F07088222C001E90814A406D0442ACA1
S210F07094001E486EFFF42F3C00000008C1
S210F070A0303900F0A18448C0D0AC0004E9
S210F070AC2F002F3C00F09A644EB900F064
S210F070B82EEADEFC0010202EFFF4720A18
S210F070C4E3A03D40FFFA7000302C002ED8
S210F070D07200322C003090812F0042A796
S210F070DC4EB900F088EC508F3D40FFF8F5
S210F070E8302EFFFA48C0322EFFF848C1E8
S210F070F40681000000FAB0816C4E3D6E84
S210F07100FFF8FFFA6046206EFFFC317CC2
S210F0710C0005000423F900F0A19400F048
S210F07118A3FC207900F0A3EC217900F035
S210F07124A3FC0010207900F0A1AE36A805
S210F071300002207900F0A1AE37500002FB
S210F0713C42AB0004276B000400083D7C0A
S210F07148111CFFFA376EFFFA000E200C48
S210F07154671C4A6B000E670C0254FFFB31
S210F07160426C004A426C004E396B000E88
S210F0716C002E426C0030200B4CEE3C0075
S210F07178FFE44E5E4E754E56FFE848EE03
S210F0718438C0FFE82A7900F0A0707C000C
S210F0719060000158486D00524EB900F047
S210F0719C8180588F28404A806614082D29
S210F071A800010001670001444EB900F041
S210F071B477086000013A306D005E48502D
S210F071C0306C000648504EB900F088DC39
S210F071CC508F2E004AAD0056672670006B
S210F071D8302D001CD0AD0014222D001845
S210F071E4D28790814A406D0001064A8672
S210F071F0660A0C87000000646D0000F8D2
S210F071FC7000302C00042D40FFFC025503
S210F07208FFF7302C000648C0BE8066265B
S210F072142F0748546100FC6E508F264097
S210F07220200B660800550008600000C84F
S210F0722C486D00524EB900F08100588FFB
S210F07238603E2F0742A76100FC48508F14
S210F072442640200B67DA2F07486B00147A
S210F07250202C00080680000000362F00FE
S210F0725C4EB900F08CAADEFC000CDFAC93
S210F0726800089F6C000649EBFFA8396E8A
S210F07274FFFE0004DFAD00189F6D005A0E
S210F07280082D000100036608082E00042C
S210F0728CFFFF6706002B0008000D4853BB
S210F072984EB900F076C8588F468037409C
S210F072A400104AAD004266102B6D00187A
S210F072B000464EB900F080D22B400042A1
S210F072BC52B900F0A3F42F3900F0A078CF
S210F072C8486D00564EB900F0813E508F25
S210F072D442A72F3C0000080048544EB9BA
S210F072E000F02F72DEFC000C7C014A6D02
S210F072EC003A6700FEA44CEE38C0FFE845
S210F072F84E5E4E754E56FFF048EE3880A5
S210F07304FFF02A7900F0A07061000096FF
S210F0731048552F3C00F06CAA4EB900F077
S210F0731C7ED6508F4EB900F08C742E0018
S210F07328287900F0A1A6264C200B672464
S210F07334BBC0660A23ED007200F0A1A6B4
S210F073406016286B0072BBCC6608276C49
S210F0734C007200726006264C200B66EA09
S210F073582F074EB900F08C88588F202DBF
S210F073640004E580068000F0A07C2040CD
S210F073704A90671A202D0004E580068085
S210F0737C00F0A07C2040429048554EB92E
S210F0738800F07C80588F42B900F0A07036
S210F07394537900F0A17E4CEE3880FFF03C
S210F073A04E5E4E754E56FFF048EE3880FC
S210F073ACFFF02A7900F0A0706010397C29
S210F073B8FFFA000448544EB900F02FCC49
S210F073C4588F486D00524EB900F0810062
S210F073D0588F28404A8066DE4EB900F068
S210F073DC8C742E006034286B000C397C9A
S210F073E8FFFA00040CAB000000010010DF
S210F073F4660A48544EB900F030C260083B
S210F0740048544EB900F02FCC588F26B937
S210F0740C00F0A06C23CB00F0A06C486DE4
S210F0741800564EB900F08100588F264058
S210F074244A8066BA2F074EB900F08C883C
S210F07430588F4CEE3880FFF04E5E4E7524
S210F0743C4E56FFEC48EE30E0FFEC2A6EF7
S210F0744800081A1502850000000FE58D04
S210F07454200D320548C1D08128401C2CC9
S210F07460000C0286000000F0E4867000CD
S210F0746C302D0002320548C19081320637
S210F0747848C1908190AE000C3E009F6D65
S210F074840002300748C0D1AC00044A6C8F
S210F07490001267109F6C00124A6C00128D
S210F0749C6606022CFFDF000D300648C02C
S210F074A8D08C320748C1D08123C000F021
S210F074B4A1984CEE30E0FFEC4E5E4E75FA
S210F074C04E56FFF82F0D2F0C2A7900F026
S210F074CCA0704AAD006E673C2F3C00003C
S210F074D800104EB900F07AF2588F2840F1
S210F074E44A80660470FF6024202D00042F
S210F074F02940000C296E00080008296DE9
S210F074FC006E000448542F3C00F0922470
S210F075084EB900F0813E508F285F2A5FDD
S210F075144E5E4E754E56FFFC2F0D2A6E94
S210F0752000082A5F4E5E4E754E56FFECDB
S210F0752C48EE3C00FFEC2A6E0008286ECB
S210F07538000C2D6C0008FFFC202EFFFC61
S210F0754406800000000E244047EA001409
S210F075507000302A00022F00102B000DF7
S210F0755C488048C02F007000302B000E56
S210F075682F002F2B00082F2B0004485596
S210F075742F3C00F09A6B4EB900F023F8A4
S210F07580DEFC001C306C000C4850306C38
S210F0758C000648502F3C00F09A974EB9CD
S210F0759800F023F8DEFC000C4CEE3C008B
S210F075A4FFEC4E5E4E754E56FFF42F0DB9
S210F075B02A7900F0A1A6200D677C082DBB
S210F075BC00020001676C23CD00F0A07008
S210F075C84A6D002E6652486EFFFA2F3C0B
S210F075D400000008303900F0A18448C028
S210F075E0D0AD00042F002F3C00F09AA95C
S210F075EC4EB900F02EEADEFC0010202E57
S210F075F8FFFA720AE3A03D40FFFE7000B0
S210F07604302D002E7200322D00309081E8
S210F076100680000000FA322EFFFE48C193
S210F0761CB280650E4EB900F078404A804F
S210F076286604005500042A6D0072200D68
S210F07634668442B900F0A0702A5F4E5E3B
S210F076404E754E56FFF82F0D2F072A6EE1
S210F0764C00084EB900F08C742E002B796C
S210F0765800F0A1A6007223CD00F0A1A661
S210F076642F074EB900F08C88588F4AAD06
S210F07670007266182F3C0000000542A7D0
S210F0767C2F3C00F06E3A4EB900F07DE2B4
S210F07688DEFC000C2E1F2A5F4E5E4E75D6
S210F076944E56FFFC2F0D2A7900F0A07077
S210F076A030150280000000036704610053
S210F076AC005C082D00020001670C610075
S210F076B801884A806604005500042A5F32
S210F076C44E5E4E754E56FFFC2F0D2A6EE3
S210F076D0000842A72F3C0000000C2F3CE6
S210F076DC00F0A3F84EB900F0855CDEFC70
S210F076E8 (   (  000C2F00303900F0A40248C05F
S210F076F42F0048554EB900F0855CDEFC17
S210F07700000C2A5F4E5E4E754E56FFF0F1
S210F0770C48EE3880FFF0287900F0A070FE
S210F0771830140280000000010C4000015C
S210F0772466047004600270002E002F0750
S210F0773042A74EB900F06E88508F2A4039
S210F0773C4A80670000F4082C00000001F2
S210F077486700009847ED001416FC0002E5
S210F0775416FC000436AC005E1B7C0060E7
S210F07760000C0254FFFE002D0002000D8D
S210F0776C0C2C000300026606022DFFEF56
S210F07778000D296C00260014202C0026C2
S210F07784528029400018102D000D48809F
S210F07790207900F0A07831400006207947
S210F0779C00F0A078317C00010008485591
S210F077A86100FF1E588F46803B4000102A
S210F077B42F3900F0A078486C00564EB953
S210F077C000F0813E508F42A72F3C0000E6
S210F077CC08002F3900F0A0684EB900F05D
S210F077D82F72DEFC000C70016054082CD0
S210F077E40001000167264AAC0052662047
S210F077F00254FFFD002D0001000D52AC0D
S210F077FC00180C2C000500026684197CB6
S210F07808000800026000FF7C2F3900F042
S210F07814A0684EB900F079BA588F2079C1
S210F0782000F0A07820B900F0A06C23F96E
S210F0782C00F0A07800F0A06C70004CEEAD
S210F078383880FFF04E5E4E754E56FFF89E
S210F078442F0D2F0C2A7900F0A07042A740
S210F0785042A74EB900F06E88508F28401A
S210F0785C4A8066047000605248546100D8
S210F07868FE60588F46803940001052B980
S210F0787400F0A404207900F0A07820B901
S210F0788000F0A06C23F900F0A07800F0F7
S210F0788CA06C2F3900F0A0684EB900F098
S210F0789830C2588F42A72F3C00000800BA
S210F078A42F3900F0A0684EB900F02F72EB
S210F078B0DEFC000C7001285F2A5F4E5EC4
S210F078BC4E754E56FFF82F0D2F0C2A7953
S210F078C800F0A1AE082D0002000D6600D6
S210F078D400A842A742A74EB900F06E884C
S210F078E0508F28404A806606700060005A
S210F078EC0092082D0004000D662A42AC45
S210F078F80004303900F0A19C48C0D0AD70
S210F07904000429400008082D0001000DCA
S210F079106608082D0000000D671252AC4F
S210F0791C0008600C022CFFEF000D296D37
S210F0792800080004002C0004000D485479
S210F079346100FD92588F4680394000102C
S210F079402F3900F0A0684EB900F030C2FD
S210F0794C588F207900F0A07820B900F0E9
S210F07958A06C23F900F0A07800F0A06C02
S210F0796442A72F3C000008002F3900F06E
S210F07970A0684EB900F02F72DEFC000C90
S210F0797C7001285F2A5F4E5E4E7500001A
S210F079884E56FFFC2F0D2F3C000006248E
S210F079944EB900F07AF2588F2A404A8074
S210F079A0671042A742A748554EB900F009
S210F079AC3062DEFC000C200D2A5F4E5E00
S210F079B84E754E56FFFC2F0D2A6E000890
S210F079C42ABC1234567848554EB900F034
S210F079D07C80588F2ABC987654327001E8
S210F079DC2A5F4E5E4E754E56FFF448EEE5
S210F079E83800FFF42A6E00086100FF96DD
S210F079F428404A8067322F3C0000062432
S210F07A00485448554EB900F08CAADEFC45
S210F07A0C000C264C41EB00362748000822
S210F07A1842A72F3C00F079BA48534EB954
S210F07A2400F03062DEFC000C200C4CEE93
S210F07A303800FFF44E5E4E754E56FFFC1C
S210F07A3C2F0D203900F09CF656800280DA
S210F07A48FFFFFFFC23C000F09CF6203986
S210F07A5400F09CFA57800280FFFFFFFC59
S210F07A6023C000F09CFA207900F09CF6A1
S210F07A6C2080203900F09CF6008000001E
S210F07A780001207900F09CFA208023F931
S210F07A8400F09CF600F0A40A23FC0000C2
S210F07A90000800F0ADDE23F900F0ADDEDB
S210F07A9C00F0ADDA203900F09CFA90B94A
S210F07AA800F09CF6588023C000F0ADE221
S210F07AB4427900F0A40842B900F0A412D9
S210F07AC0427900F0A40E427900F0A41009
S210F07ACC2A7C00F0A41660102AB900F026
S210F07AD8A41223CD00F0A412DAFC000A81
S210F07AE4BBFC00F0ADDA65E82A5F4E5EF1
S210F07AF04E754E56FFEC48EE30C0FFEC32
S210F07AFC4AAE00086E0E2F3C00F09AB068
S210F07B084EB900F08B04588F7C022F3C26
S210F07B1400000004202E00080680000090
S210F07B20000B2F004EB900F08E48508F7E
S210F07B2C2D40FFFC2E00E5872F3C0000EB
S210F07B3800202F074EB900F088EC508FAC
S210F07B442E002A7900F0A40A603220150A
S210F07B50028000000001670A601C2A9406
S210F07B5C59B900F0ADDA2855201402806C
S210F07B680000000167EC200C908DB08748
S210F07B746C2A20150280FFFFFFFE2A405E
S210F07B80BBF900F09CFA66C6538666C29D
S210F07B8C527900F0A40823F900F09CFAEF
S210F07B9800F0A40A70006056200C908DDF
S210F07BA490870C80000000206F0C200D75
S210F07BB0D087598028402895600659B907
S210F07BBC00F0ADDA23CC00F0A40A200C98
S210F07BC80080000000012A80200C220D36
S210F07BD49081D1B900F0ADDA203900F055
S210F07BE0ADDAB0B900F0ADDE6F0623C0E1
S210F07BEC00F0ADDE41ED000420084CEE89
S210F07BF830C0FFEC4E5E4E754E56FFF0AF
S210F07C0448EE30C0FFF07E002A7900F059
S210F07C109CF62015028000000001670AB8
S210F07C1C60262A9459B900F0ADDA28551D
S210F07C28201402800000000167EC200C25
S210F07C34908D2C00B0876F0823CD00F078
S210F07C40A40A2E0620150280FFFFFFFEAF
S210F07C4C2A40BBF900F09CF666BC0C87E2
S210F07C58000000046D02598720074CEE77
S210F07C6430C0FFF04E5E4E754E5600002D
S210F07C70203900F0ADE290B900F0ADDA7B
S210F07C7C4E5E4E754E56FFF82F0D2F0C86
S210F07C882A6E000841EDFFFC23C800F057
S210F07C94A40A28480294FFFFFFFE20140C
S210F07CA0908C598091B900F0ADDA7000BD
S210F07CAC103900F09D7823C000F0ADE623
S210F07CB8285F2A5F4E5E4E754E56FFFCAD
S210F07CC42F0D42B900F0A18042B900F08C
S210F07CD0ADF82A7C00F0ADFC601E2AB96E
S210F07CDC00F0ADF823CD00F0ADF82B7CE6
S210F07CE800F07F62000C3B7CFFFF0010F9
S210F07CF4DAFC0022BBFC00F0B34C65DAB2
S210F07D002F3900F09B0042A72F3C00F04B
S210F07D0C80F06100006EDEFC000C2A5FC8
S210F07D184E5E4E754E5600004AAE00104F
S210F07D24660E2F3C00F09B044EB900F0F9
S210F07D308B04588F2F3C000003E8486ED0
S210F07D3C00104EB900F08E04508F2F3C63
S210F07D480000003C486E00104EB900F041
S210F07D548D78508F42A72F2E00102F2E97
S210F07D60000C2F2E0008610000C4DEFCB2
S210F07D6C00102F00207900F09CC84E900C
S210F07D78588F4E5E4E754E5600004AAE18
S210F07D840010660E2F3C00F09B1E4EB95F
S210F07D9000F08B04588F2F3C000003E836
S210F07D9C486E00104EB900F08E04508FB8
S210F07DA82F3C0000003C486E00104EB966
S210F07DB400F08D78508F2F2E00102F2E30
S210F07DC000102F2E000C2F2E0008610083
S210F07DCC0060DEFC00102F00207900F0B4
S210F07DD89CC84E90588F4E5E4E754E566E
S210F07DE4FFFC2F0D4AAE0010660E2F3C80
S210F07DF000F09B394EB900F08B04588F61
S210F07DFC42A72F2E00102F2E000C2F2E6A
S210F07E08000861000020DEFC00102A409C
S210F07E14006D8000000C4855207900F04E
S210F07E209CC84E90588F2A5F4E5E4E7540
S210F07E2C4E56FFF448EE3080FFF44EB9DE
S210F07E3800F08C742E002A7900F0ADF8F3
S210F07E44200D660E2F3C00F09B544EB94B
S210F07E5000F08B04588F23D500F0ADF83E
S210F07E5C2F074EB900F08C88588F49EDC7
S210F07E680004397C000100042F3C0000F0
S210F07E740022200D048000F0ADFC2F0072
S210F07E804EB900F08E48508F3940000CD0
S210F07E8C0CAE00007FFF00106F08203CDA
S210F07E9800007FFF6006302E001248C08D
S210F07EA439400006302C000648C0222EA4
S210F07EB00010928029410012296E001488
S210F07EBC000E296E0008001A296E000C5B
S210F07EC80016200C4CEE3080FFF44E5EEE
S210F07ED44E754E56FFD048EE3880FFD0BA
S210F07EE047EEFFE2377C000200044EB9CB
S210F07EEC00F08C742E002A7C00F0ADFC38
S210F07EF8BBFC00F0B34C64460C6DFFFFC2
S210F07F040010674A49ED0004202C001A1B
S210F07F10B0AE0008663C202C0016B0AEA8
S210F07F1C000C6632376C000C000C48536A
S210F07F28207900F09CC84E90588F264040
S210F07F34397CFFFF000C2AB900F0ADF815
S210F07F4023CD00F0ADF82F074EB900F08E
S210F07F4C8C88588F6006DAFC002260A0DB
S210F07F584CEE3880FFD04E5E4E754E5654
S210F07F64FFF82F0D2F072A6E00082E2DB8
S210F07F7000124A876F4E0C8700007FFF5F
S210F07F7C6F08203C00007FFF6004300718
S210F07F8848C03B400006302D000648C004
S210F07F94220792802B4100123B7C00017B
S210F07FA000044855207900F09CC84E9074
S210F07FAC60122F2D0016206D001A4E906B
S210F07FB8588F48556100008E588F602CE2
S210F07FC44AAD001A6726302D000C028033
S210F07FD00000800066D80CAD00F080F0D9
S210F07FDC001A67CE48552F3C00F09D7E42
S210F07FE84EB900F0813E508F2E1F2A5F2D
S210F07FF44E5E4E754E56FFF82F0D2F0710
S210F080002F3C000025004EB900F08C88E4
S210F0800C588F2E0060142F2D0016206DEB
S210F08018001A4E90588F48556100002A60
S210F08024588F2F3C00F09D7E4EB900F007
S210F080308100588F2A404A8066D82F073F
S210F0803C4EB900F08C88588F2E1F2A5F7B
S210F080484E5E4E754E56FFF82F0D2F0CB6
S210F080542A6E00080C6DFFFF000C676A37
S210F080604AAD000E673C0CAD00007FFF40
S210F0806C000E6F083B7C7FFF00066006ED
S210F080783B6D00100006302D000648C0DE
S210F08084222D000E92802B4100123B7C57
S210F08090000100044855207900F09CC860
S210F0809C4E90588F6028026D7FFF000C9D
S210F080A8302D000CC0FC0022068000F01A
S210F080B4ADFC28403B7CFFFF000C28B918
S210F080C000F0ADF823CC00F0ADF8285F1F
S210F080CC2A5F4E5E4E754E5600002039BE
S210F080D800F0A1804E5E4E754E56000083
S210F080E423EE000800F0A1804E5E4E7502
S210F080F04E56000052B900F0A1804E5E23
S210F080FC4E7500004E56FFF448EE308043
S210F08108FFF42A6E00084EB900F08C74EC
S210F081142E002855200C670C2854204044
S210F081202094B9D4660242952F074EB9A1
S210F0812C00F08C88588F200C4CEE308051
S210F08138FFF44E5E4E754E56FFF048EE1B
S210F081443880FFF02A6E0008286E000C51
S210F081504EB900F08C742E002655200B63
S210F0815C66022A8C205528902055208CB6
S210F081682A8C2F074EB900F08C88588F38
S210F08174200B4CEE3880FFF04E5E4E758F
S210F081804E56FFF448EE3080FFF42A6EF6
S210F0818C00084EB900F08C742E00285548
S210F08198200C670228542F074EB900F0A8
S210F081A48C88588F200C4CEE3080FFF4D6
S210F081B04E5E4E754E56FFF448EE3080E2
S210F081BCFFF42A6E00084EB900F08C7438
S210F081C82E0028552F074EB900F08C88CA
S210F081D4588F200C4CEE3080FFF44E5E0E
S210F081E04E754E56FFF048EE3880FFF06B
S210F081EC2A6E0008286E000C266E0010AC
S210F081F84EB900F08C742E00B7CC660672
S210F08204429597CB60082694B9D5660228
S210F082102A8B2F074EB900F08C88588F90
S210F0821C200B4CEE3880FFF04E5E4E75E6
S210F082284E754E754E56FFEC48EE3C00CE
S210F08234FFEC2A6E0008202D00080680E3
S210F082400000000E264045EB0014286DF0
S210F0824C00084A6A0006674823EB0010A2
S210F0825800F0B35E23EB000C00F0B35A0D
S210F0826413EB000900F0B36333EA0004EB
S210F0827000F0B364423900F0B3624852EC
S210F0827C6100029E588F0C80FFFFFFFF91
S210F08288671252B900F0B35648554EB9D4
S210F0829400F02FCC588F60622F2B000CEF
S210F082A0700030122F007000302A000230
S210F082AC2F00610001C8DEFC000C2D4025
S210F082B8FFFC6C0852B900F0B35260CC2A
S210F082C438BC000239520002296B000C96
S210F082D0000441EA00082B480008302AA1
S210F082DC000448C051803B40000C3039D4
S210F082E800F09B7048C0D0AEFFFC2F00EA
S210F082F448554EB900F02F1E508F4CEE8F
S210F083003C00FFEC4E5E4E754E56FFE45F
S210F0830C48EE3C80FFE42A6E00083E2E8F
S210F083180012286D00083D6D0006FFFA0C
S210F08324423900F0B36213FC001100F0C8
S210F08330B363200C06800000000E2D4009
S210F0833CFFFC207C00F09B7822402368B9
S210F08348001800182368001400142368C6
S210F08354001000102368000C000C2368DA
S210F08360000800082368000400042290C7
S210F0836C266EFFFC23F900F0B34C00F086
S210F08378B35A277900F0B35A000C23EC3F
S210F08384000400F0B35E277900F0B35E52
S210F083900010302EFFFA48C006800000F7
S210F0839C001C37400002202EFFFC06807C
S210F083A8000000142440356C00020002B7
S210F083B43487302EFFFA48C0508033C0EB
S210F083C000F0B364357900F0B3640004FC
S210F083CC48526100014C588F4680354046
S210F083D80006066D002A0006426D000C40
S (   (  210F083E43B7C0002003242A72F3C000059
S210F083F0080048554EB900F02F72DEFC75
S210F083FC000C4CEE3C80FFE44E5E4E752C
S210F084084E56FFFC2F0D0CAE00000100DD
S210F08414000C665A4A7900F09B72675222
S210F08420427900F09B7242A72F3C00004F
S210F0842C010042A72F3C00F09B744EB9F4
S210F0843800F02EEADEFC00102F2E0010E4
S210F084444EB900F03048588F2A40202D2A
S210F08450000890AD0004528033C000F02D
S210F0845CB35033ED000600F09B7023F9DF
S210F0846800F09CEE00F0B34C70002A5FB1
S210F084744E5E4E754E56FFE848EE3CC0DB
S210F08480FFE842477CFF303900F09B70AC
S210F0848C48C0323900F0B35048C1D0812F
S210F08498C1FC0050D0B900F09D8E2440CE
S210F084A4303900F09B70C1FC0050D0B9DD
S210F084B000F09D8E264060524A5367484C
S210F084BC49EB00304BEC00100C530002B3
S210F084C86622302D0002B06E000A66300E
S210F084D4302C0002B06E000E6626202C45
S210F084E00004B0AE0010661C30076024EC
S210F084EC302D0002B06E000A67F24A6DF8
S210F084F8000266080C46FFFF66023C0718
S210F08504D6FC00505247B5CB62AA3006F9
S210F0851048C04CEE3CC0FFE84E5E4E75D6
S210F0851C4E56FFFC2F0D2A6E000842A7FA
S210F085282F3C0000000C2F3C00F0B35A73
S210F085344EB900F0855CDEFC000C2F0059
S210F08540303900F0B36448C02F004855F6
S210F0854C4EB900F0855CDEFC000C2A5FE7
S210F085584E5E4E754E56FFF048EE20A02A
S210F08564FFF42A6E00082E3C0000000019
S210F085703E2E000E2A3C000000003A2EC2
S210F0857C0012203C00000000E49F4EF9C6
S210F0858800F08596DA9D55CFFFFC6406E7
S210F08594DB8051CFFFF40807001F6704DF
S210F085A0DA5DDB800807001E670C3E1555
S210F085AC02870000FF00DA87DB802E0557
S210F085B84847DA47D18548C04CEE20A0BA
S210F085C4FFF44E5E4E7500004E56FFF0C1
S210F085D048EE3880FFF02A6E0008302DD0
S210F085DC003448C0E780D0B900F0B36669
S210F085E82840266C0004200B6730485535
S210F085F448534EB900F086EC508F2E0075
S210F086006D344A6D000C673C4855485439
S210F0860C4EB900F08764508F4A806D2C49
S210F08618302D000C48C0DE8060223E2DA5
S210F08624000C48C748554EB900F063B093
S210F08630588F4A806618485548544EB9DA
S210F0863C00F08764508F2E0048554EB9B1
S210F0864800F02FCC588F20074CEE388046
S210F08654FFF04E5E4E754E56FFF82F0DF0
S210F086602F0C4AAE00086D36202E0008E5
S210F0866CB0B900F0B36A6E2AE780D0B90F
S210F0867800F0B3662A40286D0004200CC9
S210F0868467182F2E00102F2E000C485404
S210F086904EB900F03090DEFC000C7001DB
S210F0869C60027000285F2A5F4E5E4E758C
S210F086A84E560000202E0008E7802F0041
S210F086B44EB900F07AF2588F23C000F0A8
S210F086C0B366660470006020202E0008F0
S210F086CCE7802F002F3900F0B3664EB99F
S210F086D800F08D00508F23EE000800F03C
S210F086E4B36A70014E5E4E754E56FFF401
S210F086F048EE3080FFF42A6E0008286E7A
S210F086FC000C302D000648C0322D000C9B
S210F0870848C190812E00660470FF6046A9
S210F08714306C000C48502F074EB900F0F7
S210F0872088DC508F2E00671C2F07302DD1
S210F0872C000C48C0D0AD00082F002F2C29
S210F0873800084EB900F08CAADEFC000C25
S210F08744DF6D000C302C0004816D00048A
S210F087509F6C000CDFAC000820074CEE1D
S210F0875C3080FFF44E5E4E754E56FFF473
S210F0876848EE3800FFF42A6E0008286E79
S210F08774000C306C000C48502F3C00004D
S210F0878001004EB900F088EC508F068027
S210F0878C000000362F004EB900F07AF224
S210F08798588F26404A80660670FF60008E
S210F087A4008C41EB003627480008306CD3
S210F087B0000C48502F3C000001004EB9B1
S210F087BC00F088EC508F37400006376C59
S210F087C8000C000C7000302C0004008048
S210F087D40000400037400004376C003412
S210F087E00034377CFFFF00304A6C000CC1
S210F087EC6718306C000C48502F2B00086B
S210F087F82F2C00084EB900F08CAADEFC16
S210F08804000C4AAD0004661048552F3CEE
S210F0881000F0B36E4EB900F0813E508FC1
S210F0881C4853486D00044EB900F0813E51
S210F08828508F302C000C48C04CEE38008E
S210F08834FFF44E5E4E754E56FFF448EE14
S210F088403800FFF42A7900F0B36E200D2B
S210F0884C676A284D2A55486D00044EB9A6
S210F0885800F08180588F2F004EB900F021
S210F088646440588F4A80663C486D000463
S210F088704EB900F08100588F26402F0013
S210F0887C4EB900F02FCC588F48534EB980
S210F0888800F063B0588F4AAD000466BEE6
S210F08894485448552F3C00F0B36E4EB927
S210F088A000F081E2DEFC000C4AB900F0AB
S210F088ACB36E6708BBF900F0B36E66967A
S210F088B84CEE3800FFF44E5E4E750000EB
S210F088C4202F000490AF0008670C2F0077
S210F088D0303C0001805748C04A9F4E75AF
S210F088DC202F0004B0AF00086F04202F1F
S210F088E800084E75202F0004B0AF00080A
S210F088F46C04202F00084E75202F0004A6
S210F08900B0AF00086304202F00084E758E
S210F0890C202F0004B0AF00086404202FF9
S210F0891800084E754E56FFF82F0D2F0C81
S210F089242A6E0008286E000C1015B01C1F
S210F0893066084A1D66F67000600E101512
S210F0893C488048C01224488148C1908151
S210F08948285F2A5F4E5E4E754E56FFF418
S210F0895448EE3800FFF42A6E0008286E8B
S210F08960000C264D1ADC66FC200B4CEEDA
S210F0896C3800FFF44E5E4E754E56FFF4D9
S210F0897848EE20C0FFF4602E2A7900F0D4
S210F089849D7A0C87FFFFFFFF66063E2D75
S210F08990001860043E2D001A48C70C8743
S210F0899C0000270F6644002D00020023A8
S210F089A84EB900F029B02E2E00080C8707
S210F089B4FFFFFFFF67C60C87FFFFFFFE0B
S210F089C067BE7C001C0748C64A866D0C9B
S210F089CC303900F091F448C0BC806F0E0B
S210F089D82F3C00F09B9C4EB900F08B0486
S210F089E4588F7000100748C0E98006802D
S210F089F000F091E44CEE20C0FFF44E5E68
S210F089FC4E754E56FFFC2F0D2A7C00F046
S210F08A0891DE601C2F152F2E00084EB9D2
S210F08A1400F0891C508F4A806608302D58
S210F08A20000448C0600C5C8D4A9566E0CF
S210F08A2C203C0000270F2A5F4E5E4E75BF
S210F08A384E56FFF82F0D2F072A6E000890
S210F08A44200D6608203C0000270F60267E
S210F08A504A1567F448556100FFA6588FE1
S210F08A5C2E000C800000270F660E2F3C4A
S210F08A6800F09BB34EB900F08B04588F62
S210F08A7420072E1F2A5F4E5E4E754E56F1
S210F08A80FFF82F072F06603A0C87FFFF68
S210F08A8CFFFF660C207900F09D7A3E2873
S210F08A980018600A207900F09D7A3E2855
S210F08AA4001A48C70C870000270F664A2F
S210F08AB0207900F09D7A002800020023D8
S210F08ABC4EB900F029B02E2E00080C87F2
S210F08AC8FFFFFFFF67BA0C87FFFFFFFE02
S210F08AD467B27C001C0748C64A866D0C92
S210F08AE0303900F091F448C0BC806F0EF6
S210F08AEC2F3C00F09BCD4EB900F08B0440
S210F08AF8588F20072C1F2E1F4E5E4E7568
S210F08B044E56FFFC4EB900F08C742D406D
S210F08B10FFFC2F3C00F0B3724EB900F0F2
S210F08B1C8CEA588F2F2E00082F2EFFFC3E
S210F08B282F3C00F09BE44EB900F023F860
S210F08B34DEFC000C2F3C00F09C074EB955
S210F08B4000F023F8588F2F3900F0B38EA9
S210F08B4C2F3900F0B38A2F3900F0B38602
S210F08B582F3900F0B3822F3900F0B37E06
S210F08B642F3900F0B37A2F3900F0B3760A
S210F08B702F3900F0B3722F3C00F09C3060
S210F08B7C4EB900F023F8DEFC00242F3C7D
S210F08B8800F09C514EB900F023F8588F16
S210F08B942F3900F0B3AE2F3900F0B3AA72
S210F08BA02F3900F0B3A62F3900F0B3A276
S210F08BAC2F3900F0B39E2F3900F0B39A7A
S210F08BB82F3900F0B3962F3900F0B3927E
S210F08BC42F3C00F09C7B4EB900F023F82C
S210F08BD0DEFC0024203900F0B3B259801F
S210F08BDC2F002F3C00F09C9C4EB900F0DF
S210F08BE823F8508F52AE000860FA4E756D
S210F08BF44E56FFFC2F072F3C00F09CB400
S210F08C004EB900F023F8588F528760FC45
S210F08C0C4E7500002F09226F0008206F44
S210F08C18000C202F0010600210D151C894
S210F08C24FFFC225F4E752F09226F00083F
S210F08C30206F000C202F0010600212983D
S210F08C3C51C8FFFC225F4E75206F00044C
S210F08C48428010104E75206F0004202FA4
S210F08C54000810800280000000FF4E7543
S210F08C60206F0004202F00081080101079
S210F08C6C0280000000FF4E7540C0007C47
S210F08C7807004E7540C0027CF8FF4E75F9
S210F08C8440C04E7540C046EF00064E752E
S210F08C9048E7FFFC4CF9030000F09CCC19
S210F08C9C48D0C0004CD1C0004CDF3FFFB9
S210F08CA84E752F092F01202F0014226FAC
S210F08CB4000C206F0010220982AF0010A8
S210F08CC00801000066182200E48860023C
S210F08CCC20D951C8FFFC02810000000314
S210F08CD82001600210D951C8FFFC2008F3
S210F08CE4221F225F4E754850206F0008DB
S210F08CF048D0FFFF215F0020216E00043A
S210F08CFC00404E752F01202F000C206F5A
S210F08D08000822088280080100006610B7
S210F08D14E2886002425851C8FFFC221FA3
S210F08D204E75421851C8FFFC60F4102F8E
S210F08D2C0007E148102F00064E7500000E
S210F08D384E56FFF048EE3080FFF02A6E3A
S210F08D440008286E000C2E2E0010B9CD92
S210F08D5066166018101D488048C0121C03
S210F08D5C488148C190812D40FFFC66065F
S210F08D6853876CE870004CEE3080FFF093
S210F08D744E5E4E754E56000048E73C0080
S210F08D802A3C00000001206E00082010C5
S210F08D8C6C04448044852600222E000C67
S210F08D986C044481448528010C81000125
S210F08DA400006C144240484080C13400CF
S210F08DB0300380C1484030024840603676
S210F08DBCE280E28102807FFFFFFF028170
S210F08DC87FFFFFFF0C81000100006CE84C
S210F08DD480C102800000FFFF24002F008A
S210F08DE02F044EB900F0902C508FB68097
S210F08DEC6C02538220024A856C02448020
S210F08DF820804CDF003C4E5E4E75000004
S210F08E0448E73800206F00102410280209
S210F08E106C0000044482262F00146C0056
S210F08E1C0006448344843002C0C33202D7
S210F08E284842C4C34843C2C3D28248414B
S210F08E344241D0814A846C000004448067
S210F08E4020804CDF001C4E754E560000E3
S210F08E4C48E73C002A3C00000001202E05
S210F08E5800086C04448044852600222E9E
S210F08E64000C6C044481448528010C814D
S210F08E70000100006C144240484080C135
S210F08E7C3400300380C14840300248400B
S210F08E886036E280E28102807FFFFFFF90
S210F08E9402807FFFFFFF0C810001000051
S210F08EA06CE880C102800000FFFF240098
S210F08EAC2F002F044EB900F0902C508FD1
S210F08EB8B6806C02538220024A856C02E1
S210F08EC444804CDF003C4E5E4E75000013
S210F08ED048E73800242F001028026C0041
S210F08EDC00044482262F00146C000006F0
S210F08EE8448344843002C0C33202484287
S210F08EF4C4C34843C2C3D2824841424186
S210F08F00D0814A846C00000444804CDFF2
S210F08F0C001C4E7548E73000242F000CC7
S210F08F1822026C0000044482262F001099
S210F08F246C000006448344813002C0C399
S210F08F304842C4C348424242D0824A8104
S210F08F3C6C00000444804CDF000C4E7506
S210F08F484E56000048E73800202E0008C7
S210F08F542600222E000C28010C810001E3
S210F08F6000006C18484002800000FFFF84
S210F08F6C80C13400300380C14840300261
S210F08F7848406036E280E28102807FFF15
S210F08F84FFFF02817FFFFFFF0C81000161
S210F08F9000006CE880C102800000FFFFCB
S210F08F9C24002F002F044EB900F0902C9B
S210F08FA8508FB6806C02538220024CDF23
S210F08FB4001C4E5E4E7500004E5600008D
S210F08FC048E73000202E00082400222E87
S210F08FCC000C0C81000100006C0000148A
S210F08FD84240484080C1300280C1424058
S210F08FE448406000003C2601E280E2817C
S210F08FF002807FFFFFFF02817FFFFFFF83
S210F08FFC0C81000100006C00FFE880C152
S210F0900802800000FFFF2F002F034EB97F
S210F0901400F0902C508FB4806C0290831B
S210F09020908244804CDF000C4E5E4E75D3
S210F0902C48E73000242F000C262F001020
S210F090383002C0C332024842C4C34843B2
S210F09044C2C3D28248414241D0814CDFCA
S208F09050000C4E7558
S210F09054400000800080000000000000DB
S210F090600000000000F0467000F0460A29
S210F0906C00F0648C000000000000000023
S210F090780A25730A000A4E6F6465277321
S210F09084204E6574776F726B20416464B8
S210F09090726573736573202D0A00496E3C
S210F0909C7465726E65743A2030782538E2
S210F090A8580A0045746865726E65743AEC
S210F090B420307800253278000A4C414E3F
S210F090C02047617465776179206E6F645C
S210F090CC653A2030782538580A005379B1
S210F090 (   (  D87374656D20696E697469616CD4
S210F090E4697A6174696F6E20636F6D70BE
S210F090F06C657465640A0A00000000F06D
S210F090FC9D0200F09D0200000000000045
S210F09108000000000000000A000000104C
S210F09114000000083031323334353637B6
S210F0912038394142434445460000000048
S210F0912C00000000000000000000000042
S210F0913800000000000000000000000036
S210F09144031803020300030403440301B5
S210F091500300030503EA030303E100003C
S210F0915C000B02FF025F02010062000B35
S210F09168000D0000000D00000062000B7F
S210F09174000D0000000D00000062000B73
S210F09180000D0000000D00000062000B67
S210F0918C000D0000000D0000026F000057
S210F09198001C00000000000000000000BA
S210F091A40000000000F0222473797374C1
S210F091B0656D00000000000000000000EC
S210F091BC000000000800000000000000AA
S210F091C8000000000000000000000000A6
S210F091D4000100F0B3B600F1DFF000F090
S210F091E091F60000000000000000000007
S210F091EC00000000000000000000000082
S210F091F8000064736368643A20737461CE
S210F09204636B206F766572666C6F770007
S210F09210676574706374653A20626164F0
S210F0921C207069640000000000000000F4
S210F0922800F0947C000000000000000243
S210F0923400F0443C00F0443E00F046C45D
S210F0924000F044E000F0458A00F0948254
S210F0924C00000000FFFFFFFF00F03128DC
S210F0925800F0312A00F0312C00F0315C00
S210F0926400F0318C00000000000000005C
S210F09270000000000000000000000000FD
S210F0927C000000000000000000000000F1
S210F0928800F094830000080000000800CE
S210F0929400F039DC00F039DE00F03A5053
S210F092A000F03AE800F039E000F09486A8
S210F092AC000008060000080600F03C1C5D
S210F092B800F03C1E00F03E3400F03C20BD
S210F092C400F03C2200F0948A000000004D
S210F092D0FFFFFFFF00F0479000F0479211
S210F092DC00F0479400F047EE00F0481653
S210F092E800000000000000000000000085
S210F092F400000000000000000000000079
S210F09300000000000000000000F0949157
S210F0930C000000060000000600F04B30E9
S210F0931800F04CD400F04F7600F04FC888
S210F0932400F04D5800F094950000000199
S210F093300000000100F0410400F04106CF
S210F0933C00F0410800F0410A00F0410C7F
S210F0934800F0949A0000001100000011E4
S210F0935400F0822800F0822A00F0822C44
S210F0936000F0830800F0840800F0949EF3
S210F0936C00000000FFFFFFFF00F048FCD0
S210F0937800F048FE00F0490000F04992BA
S210F0938400F04A26000000000000000088
S210F09390000000000000000000000000DC
S210F0939C000000000000000000000000D0
S210F093A800F094A2FFFFFFFFFFFFFFFFA6
S210F093B400F05C6C00F05D9000F05ED203
S210F093C000F05E5200F05F6A00F094A926
S210F093CCFFFFFFFFFFFFFFFF00F0377011
S210F093D800F0377200F0380200F0377436
S210F093E400F0388200F094B0FFFFFFFFAE
S210F093F0FFFFFFFF00F0351000F0351214
S210F093FC00F0359400F0351400F0361444
S210F0940800F094B7FFFFFFFFFFFFFFFF30
S210F0941400F032B000F032B200F033345A
S210F0942000F032B400F033B400F094BE5C
S210F0942C00000000FFFFFFFF00F03128FA
S210F0943800F0312A00F0312C00F0315C1E
S210F0944400F0318C00000000000000007A
S210F094500000000000000000000000001B
S210F0945C0000000000000000000000000F
S210F0946800F0922800F0928800F09308C4
S210F0947400F093A8000000006574686526
S210F094807200006970006172700072618A
S210F0948C77657468007463700069636DA7
S210F0949870007564700072697000696600
S210F094A45F7463700069665F75647000AA
S210F094B069665F7269700069665F65743B
S210F094BC6800000000F094D400F094D992
S210F094C800F094E100F094EB00F094F556
S210F094D44C696E6B004E6574776F726B1F
S210F094E0005472616E73706F7274004975
S210F094EC6E7465726661636500496E760A
S210F094F8616C696400496E707574004F7A
S210F095047574707574002A2A2A204465DD
S210F095106661756C74203C25733E2020CC
S210F0951C4275666665723A2025582020DD
S210F095284C6576656C3A202578205B25B3
S210F09534735D0A0042444F4E452041642F
S210F0954064726573733A2025580A0062C6
S210F0954C5F6C696E6B3A20255820206298
S210F095585F666C6167733A20257820206F
S210F09564625F6C656E3A2025782020626D
S210F095705F616464723A2025580A0062BD
S210F0957C5F6D73676C656E3A20257820F2
S210F0958820625F726573763A202578202A
S210F0959420625F6465766963653A202506
S210F095A0780A00625F6164647220636FFA
S210F095AC6E74656E74733A0A002532780F
S210F095B8000A000A00000000000000009E
S210F095C40000000169665F6574683A20DC
S210F095D0496E707574206F6E20636C6F2F
S210F095DC736564206368616E20254420EF
S210F095E85B25585D0A0069665F657468D4
S210F095F4007261776574680069665F6558
S210F096007468000000000000000000018C
S210F0960C69665F7269703A20496E7075EE
S210F0961874206F6E20636C6F7365642026
S210F096246368616E202544205B25585DCD
S210F096300A0069665F726970007269706B
S210F0963C0069665F7269700000000000B4
S210F096480000000169665F7564703A204F
S210F09654496E707574206F6E20636C6FAA
S210F09660736564206368616E202544206A
S210F0966C5B25585D0A0069665F75647047
S210F09678007564700069665F7564700031
S210F09684000169636D70006172700000F8
S210F09690FFFFFFFFFFFF00014152503AC1
S210F0969C206475706C6963617465204989
S210F096A85020616464726573730A000061
S210F096B4000000000000000000000000B5
S210F096C0000000000000000000000000A9
S210F096CC0000000000000000000000009D
S210F096D800000000000000000000000091
S210F096E400000000000000000000000085
S210F096F000000000000000000000000079
S210F096FC0000000000000000000000006D
S210F0970800000000000000000000000060
S210F0971400000000000000000000000054
S210F0972000000000000000000000000048
S210F0972C0000000000000000000000003C
S210F0973800000000000000000000000030
S210F0974400000000000000000000000024
S210F0975000000000000000000000000018
S210F0975C0000000000000000000000000C
S210F0976800000000000000000000000000
S210F09774000000000000000000000000F4
S210F09780000000000000000000000000E8
S210F0978C000000000000000000000000DC
S210F09798000000000000000000000000D0
S210F097A4C00529FE0000000000000000D8
S210F097B0000000000000000000000001B7
S210F097BC556E61626C6520746F20416C85
S210F097C86C6F6361746520526563656920
S210F097D4766520427566666572730A00C2
S210F097E0FFFF0001657468657200000071
S210F097ECFFFF000169700000450000144B
S210F097F8000000000A0000000000000066
S210F09804000000000001697000697000B0
S210F0981053455143484B20286F726465A6
S210F0981C7229206578706563742025586A
S210F0982820676F742025580A0069665F00
S210F09834746370007263767572673A20F9
S210F0984030206C656E67746820757267E7
S210F0984C656E742064617461202D20634A
S210F0985868616E2025640A00496E746595
S210F0986472666163652042465220466141
S210F09870696C7572652025580A0000002F
S210F0987CFFFFFFFF0000000174637000A7
S210F0988869665F7463703A204F70656E7E
S210F09894202D206368616E202564205BA8
S210F098A025585D20006C697374656E201E
S210F098AC706F72742025640A00636F6E03
S210F098B86E65637420706F727420256477
S210F098C40A007463700069665F746370DD
S210F098D03A20436C6F7365202D2063680F
S210F098DC616E202564205B25585D0A00B4
S210F098E869665F7463703A20496E707514
S210F098F474206F6E206672656520636855
S210F09900616E202544205B25585D0A00AF
S210F0990C7463700069665F74637000742A
S210F0991863700069665F74637000696637
S210F099245F7463703A205369676E616CE4
S210F09930206F6E20636C6F736564202D52
S210F0993C206368616E2025640A007463E6
S210F09948700069665F7463703A20536923
S210F0995467202564202D206368616E20DB
S210F099602564205B25585D0A00746370D7
S210F0996C007463700000000000F0A1B270
S210F0997850726F746F636F6C3A202573AA
S210F09984202053746172743A2025642091
S210F09990456E643A2025640A00556E6BA4
S210F0999C6E6F776E2070726F746F636FE2
S210F099A86C3A2025730A004461746120BC
S210F099B46368616E6E656C206172726113
S210F099C07920616C6C6F636174696F6EE7
S210F099CC206661696C6564210A00454E57
S210F099D850204641494C555245210041B4
S210F099E46C6C6F63617465642025642071
S210F099F06368616E6E656C732C20646119
S210F099FC74615F6368616E206174202562
S210F09A08580A00416C6C6F636174656472
S210F09A1420254420486F737420627566AD
S210F09A20666572732061742025580A00F9
S210F09A2C467265656D656D2025580A00D1
S210F09A385443503A204E6F7420656E6F59
S210F09A44756768206D656D20746F2061FA
S210F09A506C6C6F63617465207274782093
S210F09A5C626672730069700069665F74E1
S210F09A686370002573207365713A253892
S210F09A74582061636B3A2538582077695B
S210F09A806E646F773A25782063746C3AB9
S210F09A8C2578206C656E3A25780A0020DC
S210F09A98636E743A202544207265733A21
S210F09AA42025440A0069665F74637000B9
S210F09AB0696E76616C696420616C6C6F06
S210F09ABC6320726571756573740000001D
S210F09AC80000000000000000000000009D
S210F09AD4000045000028000000000A0614
S210F09AE000000000000000000000000085
S210F09AEC00000000000000000000501019
S210F09AF80000000000000000000000016C
S210F09B04616C61726D20776974682062F5
S210F09B1061642064656C61792074696DF6
S210F09B1C650069616C61726D20776974F9
S210F09B2868206261642064656C6179203E
S210F09B3474696D650066616C61726D20EE
S210F09B4077697468206261642064656CCC
S210F09B4C61792074696D65004F75742017
S210F09B586F662054696D657220517565CB
S210F09B64756520456E747269657300002C
S210F09B70FFFF0001697000004500001CBB
S210F09B7C000000000A11000000000000CD
S210F09B88000000000000000000000000DC
S210F09B940000000000000000676574642C
S210F09BA06374653A2042616420446576E8
S210F09BAC696365204964006376646576A2
S210F09BB86E6D3A20646576696365206E79
S210F09BC46F7420666F756E640072656149
S210F09BD06C6469643A206261642064658D
S210F09BDC76696365206964006572726F3C
S210F09BE8722068616C743A206F6C642088
S210F09BF4737461747573203D20255820B2
S210F09C002D2D2025730A00202044302073
S210F09C0C2020443120202044322020206C
S210F09C1844332020204434202020443523
S210F09C24202020443620202044370A0080
S210F09C30253458202534582025345820C0
S210F09C3C253458202534582025345820B4
S210F09C48253458202534580A002020410E
S210F09C543020202041312020204132201A
S210F09C602020413320202041342020201A
S210F09C6C204135202020204136202041E9
S210F09C78370A00253458202534582025E3
S210F09C843458202534582025345820256C
S210F09C90345820253458202534580A009B
S210F09C9C7379736572722063616C6C65FE
S210F09CA8642066726F6D202534580A00A8
S210F09CB42A2A657869742063616C6C6580
S20CF09CC0642A2A0A00000000E5
S804F02000EB
A
S210F08FD84240484080C1300280C1424058
S210F08FE448406000003C2601E280E2817C
S210F08FF002807FFFFFFF02817FFFFFFF83
S210F08FFC0C81000100006C00FFE880C152
S210F0900802800000FFFF2F002F034EB97F
S210F0901400F0902C508FB4806C0290831B
S210F09020908244804CDF000C4E5E4E75D3
S210F0902C48E73000242F000C262F00102unix/                                                                                                  775     322     145            0  4104216762   5030                                                                                                                                                                                                                                                                                                                                                                       (   (  unix/include/                                                                                          750     322     145            0  3621344561   6446                                                                                                                                                                                                                                                                                                                                                                      unix/include/CMC/                                                                                      750     322     145            0  3723116646   7054                                                                                                                                                                                                                                                                                                                                                                      unix/include/CMC/CMC_proto.h                                                                           444     322     145         3653  3621344545  11147                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */


/*
 * Protocol switch table.
 *
 * Each protocol has a handle initializing one of these structures,
 * which is used for protocol-protocol and system-protocol communication.
 *
 * The userreq routine interfaces protocols to the system and is
 * described below.
 */

typedef
struct protosw {
	short	pr_type;		/* socket type used for */
	short	pr_family;		/* protocol family */
	short	pr_protocol;		/* protocol number */
	short	pr_flags;		/* see below */
	int	(*pr_cmp)();		/* name checker; 0 => OK */
	int	(*pr_nmck)();		/* more name checking */
	int	(*pr_gname)();		/* get name */
	int	(*pr_bind)();		/* Protocol specific bind	*/
	int	(*pr_connect)();	/* Protocol specific connect	*/
	int	(*pr_close)();		/* Protocol specific close	*/
	int	(*pr_send)();		/* Protocol specific send	*/
	int	(*pr_recv)();		/* Protocol specific recv	*/
	short	pr_channel;		/* h_chan[] offset for protocol */
	short	pr_end;			/* End of available channels	*/
	short	pr_next;		/* Next h_chan[] for allocation */
	short	pr_offset;		/* data offset			*/
	short	pr_maxdata;		/* max user data		*/
} PROTO;

/*
 * Values for pr_flags
 */
#define	PR_ATOMIC	0x01		/* exchange atomic messages only */
#define	PR_ADDR		0x02		/* addresses given with messages */
/* in the current implementation, PR_ADDR needs PR_ATOMIC to work */
#define	PR_CONNREQUIRED	0x04		/* connection required by protocol */
#define	PR_WANTRCVD	0x08		/* want PRU_RCVD calls */
#define	PR_RIGHTS	0x10		/* passes capabilities */

/*
 * Structure per communications domain.
 */
typedef
struct	domain {
	int	dom_family;		/* AF_xxx */
	char	*dom_name;
	struct	protosw *domps, *domps_END;
	struct	domain *dom_next;
} DOMAIN;

00F0822800F0822A00F0822C44
S210F0936000F0830800F0840800F0949EF3
S210F0936C00000000FFFunix/include/CMC/CMC_socket.h                                                                          444     322     145        14663  3711751032  11310                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	This file defines the data structures used to communicate
 *	between an ENP and a Unix host.
 *
 *	This file is needed by a device-driver type interface to
 *	an ENP.  It presumes data structure formats as defined
 *	in <CMC/user_socket.h>.
 */

#define CHANSIZE	4
#define NCHANS		32
#define NSOCKETS 	32
#define SOMAXCONN 	5
#define SOCKNAMESIZE	32

/*
 *	Formats of shared data structures
 */

/*
 * per connection data flow channels 
 */

typedef struct sring
{
	char	s_rdidx;
	char	s_wrtidx;
} SRING;

/*
 *	macros to manipulate "shadow" rings.
 *
 *	There are some assumptions built in here regarding the
 *	size of ring involved.  Invoking sringput if sringfull is true
 *	will almost certainly result in disaster.
 */

# define sringinit(key) ( data_chan[ (key) ].c_sring.s_rdidx = data_chan[ (key) ].c_sring.s_wrtidx = 0 )
# define sringempty(sp) ( (sp)->s_wrtidx == (sp)->s_rdidx )
# define sringfull(sp) ( (((sp)->s_wrtidx+1) & (CHANSIZE-1)) == ((sp)->s_rdidx&(CHANSIZE-1)) )
# define sringput(sp)  ( (sp)->s_wrtidx = ((sp)->s_wrtidx + 1) & (CHANSIZE-1) )
# define sringget(sp)  ( (sp)->s_rdidx = (((sp)->s_rdidx)+1) & (CHANSIZE-1) )

typedef struct chan
{
	short	c_state;		/* state of channel */
	short	c_pgrp;			/* process group for urgent */
	short	c_options;		/* socket level options */
	short	c_inflight;		/* number in use */
	BFR	*c_opbfr;		/* bfr waiting open to complete */
	BFR	*c_clbfr;		/* bfr waiting close to complete */
#ifndef lint
	RING/**/CHANSIZE	c_tohost;	/* bfrs for the host */
#else
	RING4			c_tohost;
#endif
	SRING	c_sring;		/* shadow ring */
	short	c_pad;
	caddr_t	c_selproc;		/* procp of selecting process */
	char 	c_name[ SOCKNAMESIZE ];	/* current name info */
}CHAN;

/*
 * bus rings
 */

typedef struct ENPDATA
{
	RING8	h_open;			/* open requests to enp */
	RING16	h_tonet;		/* data,stat,cls packets */
	RING16	h_netcomplete;		/* finished data,stat,cls packets */
	RING32  e_tohost;		/* Everything from ENP */
	RING32	e_hostcomplete;		/* Completed back from host */
	RING16	e_wakeaddr;		/* addrs to wake up on intr */
	RING8	e_urg;			/* pgrps for urgent signals */
} ENPDATA;


typedef
struct socket
{
	short		so_options;
	short		so_state;	/* See definitions below	*/
	short		so_enpid;	/* Channel Id - to/from ENP	*/
	short		so_lim_listen;
	short		so_pgrp;	/* Unix process group		*/
	short		so_nmlen;	/* Num bytes in so_name		*/
	char		so_name[SOCKNAMESIZE];  /* User supplied name	*/
	PROTO		*so_proto;	/* releated protocol		*/
	BFR		*so_o_bfr;	/* If open in prog- BFR address	*/
	struct opn	*so_o_opn;	/* and addr of params in BFR	*/
} SOCKET;


/*
 *	Values for so_state
 */

# define	SS_AVAIL	0
# define	SS_OPEN		1
# define	SS_CONNECTED	2
# define	SS_LISTEN	4
# define	SS_CONNECTING	8
# define	SS_NOREAD	0x10
# define	SS_NOWRITE	0x20
# define	SS_FLUSHING	0x40
# define	SS_BROKEN	0x80
# define	SS_RESV		0x100
# define	SS_ATMARK	0x200
# define	SS_BOUND	0x400
# define	SS_CLOSEING	0x800
# define	SS_SELCOLL	0x1000
# define	SS_ALLOC	0x2000

/*
 * Definitions related to sockets: types, address families, options.
 */

/*
 * Types
 */

#define	SOCK_STREAM	1		/* stream socket */
#define	SOCK_DGRAM	2		/* datagram socket */
#define	SOCK_RAW	3		/* raw-protocol interface */
#define	SOCK_RDM	4		/* reliably-delivered message */
#define	SOCK_SEQPACKET	5		/* sequenced packet stream */

/*
 * Option flags per-socket.
 */
#define	SO_DEBUG	0x01		/* turn on debugging info recording */
#define	SO_ACCEPTCONN	0x02		/* socket has had listen() */
#define	SO_REUSEADDR	0x04		/* allow local address reuse */
#define	SO_KEEPALIVE	0x08		/* keep connections alive */
#define	SO_DONTROUTE	0x10		/* just use interface addresses */
				/* 0x20 was SO_NEWFDONCONN */
#define	SO_USELOOPBACK	0x40		/* bypass hardware when possible */
#define	SO_LINGER	0x80		/* linger on close if data present */
#define	SO_DONTLINGER	(~SO_LINGER)	/* ~SO_LINGER */


/*
 * Address families.
 */
#define	AF_UNSPEC	0		/* unspecified */
#define	AF_UNIX		1		/* local to host (pipes, portals) */
#define	AF_INET		2		/* internetwork: UDP, TCP, etc. */
#define	AF_IMPLINK	3		/* arpanet imp addresses */
#define	AF_PUP		4		/* pup protocols: e.g. BSP */
#define	AF_CHAOS	5		/* mit CHAOS protocols */
#define	AF_NS		6		/* XEROX NS protocols */
#define	AF_NBS		7		/* nbs protocols */
#define	AF_ECMA		8		/* european computer manufacturers */
#define	AF_DATAKIT	9		/* datakit protocols */
#define	AF_CCITT	10		/* CCITT protocols, X.25 etc */
#define	AF_SNA		11		/* IBM SNA */
#define AF_ETHER	12		/* direct Ethernet access */
#define AF_ETHERLINK	12		/* direct Ethernet access */

#define	AF_MAX		13

/*
 * Protocol families, same as address families for now.
 */
#define	PF_UNSPEC	AF_UNSPEC
#define	PF_UNIX		AF_UNIX
#define	PF_INET		AF_INET
#define	PF_IMPLINK	AF_IMPLINK
#define	PF_PUP		AF_PUP
#define	PF_CHAOS	AF_CHAOS
#define	PF_NS		AF_NS
#define	PF_NBS		AF_NBS
#define	PF_ECMA		AF_ECMA
#define	PF_DATAKIT	AF_DATAKIT
#define	PF_CCITT	AF_CCITT
#define	PF_SNA		AF_SNA
#define PF_ETHER	AF_ETHER
#define PF_ETHERLINK	AF_ETHERLINK

#define	PF_MAX		AF_MAX

#define	MSG_OOB		0x1		/* process out-of-band data */
#define	MSG_PEEK	0x2		/* peek at incoming message */
#define	MSG_DONTROUTE	0x4		/* send without using routing tables */

/*
 *	Unix priority
 */

# define PENP PZERO+1

/*
 *	Variables declared elsewhere
 */

extern SOCKET sock_table[];	/* The actual sockets */

/*
 * open a connection data structure 
 */

typedef struct opn
{
	short	o_status;	/* how it came out */
	short	o_pgrp;		/* proc group for urgent sigs */
	short	o_type;		/* listen/open what */
	short	o_pad;		/* for alignment	*/
	int	o_id;		/* returned id */
	char	o_name[ SOCKNAMESIZE ];
	char	o_parm[ SOCKNAMESIZE ];
}OPN;

/*
 *	Protocol_Initialization_Block
 *
 *	Used by host to tell ENP which INTERFACE protocols to init.
 *
 *	The host will set "protosw"->pr_channel & pr_ (   (  available and
 *	the ENP will set the p_start & p_end values in the interface
 *	layer's PROTOCOL structure (proto.h) using these values.
 */

#define MAXPNAME	12

typedef struct	pib {
	short	pib_family;		/* Host protosw->pr_family	*/
	short	pib_type;		/* Host protosw->pr_type	*/
	int	pib_start;		/* ENP protocol->p_start value	*/
	int	pib_num;		/* ENP protocol->p_end		*/
	char	pib_name[MAXPNAME];	/* ENP protocol->p_name		*/
} PIB;
ce-driver type interface to
 *	an ENP.  It presumes data structure formats asunix/include/CMC/dir.h                                                                                 444     322     145         1545  3621344546  10077                                                                                                                                                                                                                                                                                                                                                                      /*	CMC/dir.h	7.0	10/10/84	*/

/*
 * This file has been created to support opendir, readdir,
 * and closedir operations on System 5 directory structures.
 *
 * October 10, 1984 - Created by Deb Brown, CMC
 */

#ifdef TARGET_SYSTEM
#if TARGET_SYSTEM == VALID
#ifndef void
#include <CMC/sysdep.h>
#endif
#endif
#endif
#ifndef NULL
#define NULL 0
#endif

#define	MAXNAMLEN	14

struct	direct {
	u_long	d_ino;			/* inode number of entry */
	char	d_name[MAXNAMLEN + 1];	/* name must be no longer than this */
};

 long	lseek();

#define closedir(fid)		(close (fid))
#define seekdir(fid, loc)	(lseek ((fid), (long) (loc), 0))
#define telldir(fid)		(lseek ((fid), (long) 0, 1))
#define rewinddir(fid)		(lseek ((fid), (long) 0, 0))


/* definitions for actual directory formats */

struct dir_s5 {				/* System 5-type direct struct */
	ino_t	d5_ino;
	char	d5_name[MAXNAMLEN];
};
re some assumptions built in here regarding the
 *	size of ring involved.  Invoking sringput if sringfull is true
 *	will almost certainly result in disastunix/include/CMC/enp.h                                                                                 444     322     145         3550  3621344547  10102                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */


/*
 *	This file defines the data structures used to communicate
 *	between an ENP and a Unix host.
 */

/*
 *	Command field values
 */

	/* From host to ENP */

# define SC_RESERVE	1
# define SC_SEND	2
# define SC_RECV	3
# define SC_CLOSE	4
# define SC_SEND_OOB	5
# define SC_PEEK	6
# define SC_STATUS	7
# define SC_CONNECT	8	/* From ENP, means connection complete */
# define SC_BIND	9
# define SC_LISTEN	10
# define SC_RECV_SIG	11
# define SC_SEND_SIG	12
# define SC_GNAMES	13
# define SC_SET_OPT	14
# define SC_GET_OPT	15

#define SC_CTL		0x8000		/* control vs data in b_flags */
#define SC_WAKE		0x80		/* want wakeup on txdone */
#define SC_FLAGS	0x60		/* confluence of two below */
#define SC_PUSH		0x20		/* tcp eol wanted - */
#define SC_URGENT	0x40		/* tcp urgent data */

	/* From ENP to host */

# define SC_HAVE_OOB	129
# define SC_ACCEPT	130	/* Listen has succeeded; reply implies relisten */
# define SC_END_OOB	131	/* host now has all OOB data */

# define SC_REPLY	(1<<15)	/* XXX */

/*
 *		Interface Data Structures
 */

# define HS_INIT	1		/* h_state -> host init'd	*/
# define ENP_INIT	1		/* h_state -> enp init'd	*/

typedef struct HOSTCTL {
	int	h_state;
	int	h_hostbase;
	int	h_enpbase;
} HOSTCTL;


typedef struct SHARED {
	int		enpbase;
	int		hostbase;
	int		hostbfraddr;
	int		numhostbfr;
	int		chanaddr;
	unsigned long	inetaddr;
	char		enetaddr[6];	/* Ethernet addr	*/
	short		status;
} SHARED;


typedef struct	SHARED_RINGS {
	RING	*h_open;
	RING	*h_tonet;
	RING	*h_netcomplete;
	RING	*e_tohost;
	RING	*e_hostcomplete;
	RING	*e_wakeaddr;
	RING	*e_urg;
} SHARED_RINGS;


	caddr_t	c_selproc;		/* procp of selecting process */
	char 	c_name[ SOCKNAMESIZE ];	/* current name info */
}CHAN;

/*
 * bus rings
 */

typedef strucunix/include/CMC/enpram.h                                                                              444     322     145          724  3621344547  10562                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */
/*
 *	ioctl definitions for enpram driver
 */

# define mkioctl(type,value) (('type'<<8)|value)

# define ENPIOC_JUMP		mkioctl(N,1)
# define ENPIOC_RESET		mkioctl(N,2)
ine SC_RESERVE	1
# define SC_SEND	2
# defineunix/include/CMC/errno.h                                                                               444     322     145         6661  3621344550  10445                                                                                                                                                                                                                                                                                                                                                                      /*
 * Define system error numbers, including the ones related to networking.
 * Include the standard system error numbers.  Then make sure that the
 * network numbers are defined as we expect them to be.  (Their actual
 * values are significant because the ENP code knows about these numbers.)
 */

#include <errno.h>			/* include standard errors */

/* non-blocking and interrupt i/o */
#ifdef	EWOULDBLOCK
# undef	EWOULDBLOCK
#endif	EWOULDBLOCK
#define EWOULDBLOCK	55		/* Operation would block */

#ifdef	EINPROGRESS
# undef	EINPROGRESS
#endif	EINPROGRESS
#define EINPROGRESS	56		/* Operation now in progress */

#ifdef	EALREADY
# undef	EALREADY
#endif	EALREADY
#define EALREADY	57		/* Operation already in progress */


	/* argument errors */
#ifdef	ENOTSOCK
# undef	ENOTSOCK
#endif	ENOTSOCK
#define ENOTSOCK	58		/* Socket operation on non-socket */

#ifdef	EDESTADDRREQ
# undef	EDESTADDRREQ
#endif	EDESTADDRREQ
#define EDESTADDRREQ	59		/* Destination address required */

#ifdef	EMSGSIZE
# undef	EMSGSIZE
#endif	EMSGSIZE
#define EMSGSIZE	60		/* Message too long */

#ifdef	EPROTOTYPE
# undef	EPROTOTYPE
#endif	EPROTOTYPE
#define EPROTOTYPE	61		/* Protocol wrong type for socket */

#ifdef	ENOPROTOOPT
# undef	ENOPROTOOPT
#endif	ENOPROTOOPT
#define ENOPROTOOPT	62		/* Protocol not available */

#ifdef	EPROTONOSUPPORT
# undef	EPROTONOSUPPORT
#endif	EPROTONOSUPPORT
#define EPROTONOSUPPORT	63		/* Protocol not supported */

#ifdef	ESOCKTNOSUPPORT
# undef	ESOCKTNOSUPPORT
#endif	ESOCKTNOSUPPORT
#define ESOCKTNOSUPPORT	64		/* Socket type not supported */

#ifdef	EOPNOTSUPP
# undef	EOPNOTSUPP
#endif	EOPNOTSUPP
#define EOPNOTSUPP	65		/* Operation not supported on socket */

#ifdef	EPFNOSUPPORT
# undef	EPFNOSUPPORT
#endif	EPFNOSUPPORT
#define EPFNOSUPPORT	66		/* Protocol family not supported */

#ifdef	EAFNOSUPPORT
# undef	EAFNOSUPPORT
#endif	EAFNOSUPPORT
#define EAFNOSUPPORT	67		/* Proto fam doesn't support addr fam */

#ifdef	EADDRINUSE
# undef	EADDRINUSE
#endif	EADDRINUSE
#define EADDRINUSE	68		/* Address already in use */

#ifdef	EADDRNOTAVAIL
# undef	EADDRNOTAVAIL
#endif	EADDRNOTAVAIL
#define EADDRNOTAVAIL	69		/* Can't assign requested address */


	/* operational errors */
#ifdef	ENETDOWN
# undef	ENETDOWN
#endif	ENETDOWN
#define ENETDOWN	70		/* Network is down */

#ifdef	ENETUNREACH
# undef	ENETUNREACH
#endif	ENETUNREACH
#define ENETUNREACH	71		/* Network is unreachable */

#ifdef	ENETRESET
# undef	ENETRESET
#endif	ENETRESET
#define ENETRESET	72		/* Network dropped connection on reset */

#ifdef	ECONNABORTED
# undef	ECONNABORTED
#endif	ECONNABORTED
#define ECONNABORTED	73		/* Software caused connection abort */

#ifdef	ECONNRESET
# undef	ECONNRESET
#endif	ECONNRESET
#define ECONNRESET	74		/* Connection reset by peer */

#ifdef	ENOBUFS
# undef	ENOBUFS
#endif	ENOBUFS
#define ENOBUFS		75		/* No buffer space available */

#ifdef	EISCONN
# undef	EISCONN
#endif	EISCONN
#define EISCONN		76		/* Socket is already connected */

#ifdef	ENOTCONN
# undef	ENOTCONN
#endif	ENOTCONN
#define ENOTCONN	77		/* Socket is not connected */

#ifdef	ESHUTDOWN
# undef	ESHUTDOWN
#endif	ESHUTDOWN
#define ESHUTDOWN	78		/* Can't send after socket shutdown */

#ifdef	ETOOMANYREFS
# undef	ETOOMANYREFS
#endif	ETOOMANYREFS
#define ETOOMANYREFS	79		/* Too many references: can't splice */

#ifdef	ETIMEDOUT
# undef	ETIMEDOUT
#endif	ETIMEDOUT
#define ETIMEDOUT	80		/* Connection timed out */

#ifdef	ECONNREFUSED
# undef	ECONNREFUSED
#endif	ECONNREFUSED
#define ECONNREFUSED	81		/* Connection refused */

interface */
#define	SOCK_RDM	4		/* reliably-delivered message */
#define	SOCK_unix/include/CMC/eth.h                                                                                 444     322     145        10160  3621344551  10106                                                                                                                                                                                                                                                                                                                                                                       (   (  /*
 *	Copyright (c) 1984 by Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is proprietary
 *	to Communication Machinery Corporation.  Duplication or disclosure
 *	of this information is prohibited without the express written
 *	authorization of Communication Machinery Corporation.
 */

/*
 *	Ethernet-style addresses
 */

typedef
struct en_addr {
	char	ena_addr[6];
} en_addr;

typedef
struct sockaddr_eth {
	short	sen_family;
	u_short	sen_type;		/* Ethernet type code */
	en_addr	sen_addr;
	char	sen_zero[4];
} sockaddr_eth;

# define ETHTYPE_ANY 0xFFFF

/*
 *	Definitions for getsockopt and setsockopt
 *
 *	Usage is:
 *		unsigned short arg;
 *		setsockopt (s, SOL_ETHER, EIOCSETMODE, &arg, sizeof (arg));
 */

# define SOL_ETHER 0

# define EIOCSETMODE (128)
# define EIOCGETMODE (129)
# define EIOCGETSTAT (130)
# define EIOCCLRSTAT (131)
# define EIOCGETSTATCLR (132)
# define EIOCSETIME (133)
# define EIOCSETTIME EIOCSETIME
# define EIOCSETBUF (134)
# define EIOCGETBUF (135)

/*
 *	Bit definitions for SETMODE
 *	(may be OR'd together)
 */

# define PROMISCUOUS 0x8000
# define DOSOURCE    0x4000
# define USEADDR     0x2000	/* use supplied src, not node address */
# define LOOPINTERN  0x0040
# define DONTRETRY   0x0020
# define FRCECOLLIDE 0x0010
# define NOXMITCRC   0x0008
# define LOOPBACK    0x0004
# define NOXMITTER   0x0002
# define NORECVER    0x0001

/*
 *	Bits returned by GETMODE
 *		Many of these indicate potential errors, but there is 
 *		no way to correlate the errors with any particular Unix
 *		read or write.
 */

# define ANYERROR	0x8000
# define BABBLE		0x4000
# define COLLISION	0x2000
# define MISS		0x1000
# define MEMERR		0x0800
# define RCVINT		0x0400
# define XMITINT	0x0200
# define INITDONE	0x0100
# define INTPENDING	0x0080
# define INTENABLE	0x0040
# define RCVRON		0x0020
# define XMITON		0x0010
# define DEMANDXMIT	0x0008
# define STOPPED	0x0004
# define STARTED	0x0002
# define INITIALIZE	0x0001

/*
 *	ioctl structures for statistics/mode
 */

typedef
struct eth_io_stat
{
	unsigned long e_xmit_successful;	/* Successful transmissions */
	unsigned long e_mult_retry;		/* multiple retries on xmit */
	unsigned long e_one_retry;		/* single retries */
	unsigned long e_fail_retry;		/* too many retries */
	unsigned long e_deferrals;		/* transmission delayed due
						   to active medium */
	unsigned long e_xmit_buff_err;		/* xmit data chaining failed --
						   "can't happen" */
	unsigned long e_silo_underrun;		/* transmit data fetch failed */
	unsigned long e_late_coll;		/* collision after xmit */
	unsigned long e_lost_carrier;
	unsigned long e_babble;			/* xmit length > 1518 */
	unsigned long e_collision;
	unsigned long e_xmit_mem_err;
	unsigned long e_rcv_successful;		/* good receptions */
	unsigned long e_rcv_missed;		/* no recv buff available */
	unsigned long e_crc_err;		/* checksum failed */
	unsigned long e_frame_err;		/* crc error AND
						   data length != 0 mod 8 */
	unsigned long e_rcv_buff_err;		/* rcv data chain failure --
						   "can't happen" */
	unsigned long e_silo_overrun;		/* receive data store failed */
	unsigned long e_rcv_mem_err;
} Eth_Io_Stat;

/*
 * Bits of errno for read errors.
 */

#define ER_FRAM	0x20	/* A framing error occurred. */
#define ER_OFLO	0x10	/* A SILO overflow occured. */
#define ER_CRC	0x08	/* A CRC error was detected. */
#define ER_BUFF	0x04	/* A receive buffer error occurred. */
#define ER_MERR	0x02	/* A memory error occurred on receive. */
#define ER_MISS	0x01	/* A missed packet was reported. */

/*
 * Bits of errno for write errors.
 */
#define EX_UFLO	0x40	/* Silo underflow occurred on transmission. */
#define EX_BABL	0x20	/* A babbling transmitter error was reported. */
#define EX_LCOL	0x10	/* A late collision occurred on transmission. */
#define EX_CAR	0x08	/* Carrier was lost during transmission. */
#define EX_RTRY	0x04	/* Retry failure. */
#define EX_MERR	0x02	/* A memory error occured on transmit. */
#define EX_CERR	0x01	/* A collision error was reported. */

#if !defined(vax)
/*
 * Macros for number representation conversion.
 */
#define	ntohl(x)	(x)
#define	ntohs(x)	(x)
#define	htonl(x)	(x)
#define	htons(x)	(x)
#endif
ne	AF_UNSPEC	0		/* unspecified */
#define	AF_UNIX		1		/* local to host (pipes, portals) */
#define	AF_INET		2		/* internetwork: UDP, TCP, etc. */
#define	AF_IMPLINK	3		/* arpanet imp addresses */
#define	AF_PUP		4		/* pup protocols: e.g. BSP */
#define	AF_CHAOS	5		/* mit CHAOS protocols */
#define	AF_NS		6		/* XEROX NS protocols */
#define	AF_NBS		7		/* nbs protocols */
#define	AF_ECMA		8		/* eurounix/include/CMC/eth_proto.h                                                                           444     322     145          230  3621344551  11266                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Ethernet protocol types
 */

# define ETHPROTO_RAW	255

# define ETHPROTO_MAX	256

extern struct domain ethdomain;
extern struct protosw ethsw[];
ication Machinery Corporation.  Duplication or disclosure
 *	of this information is prohibited without the express written
 *	authorization of Communication Machinery Corporation.
 */

/*
 *	Ethernet-style addresses
 */

typedef
struct en_addr {
	char	ena_addr[6];
} en_addr;

typedef
struct sockaddr_eth {
	short	sen_family;
	u_short	sen_type;		/* Ethernet tyunix/include/CMC/ftp.h                                                                                 444     322     145         3251  3621344552  10103                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	ftp.h	4.1	83/01/13	*/
/*
 * Definitions for FTP
 * See RFC-765
 */

/*
 * Reply codes.
 */
#define PRELIM		1	/* positive preliminary */
#define COMPLETE	2	/* positive completion */
#define CONTINUE	3	/* positive intermediate */
#define TRANSIENT	4	/* transient negative completion */
#define ERROR		5	/* permanent negative completion */

/*
 * Type codes
 */
#define	TYPE_A		1	/* ASCII */
#define	TYPE_E		2	/* EBCDIC */
#define	TYPE_I		3	/* image */
#define	TYPE_L		4	/* local byte size */

/*
 * Form codes
 */
#define	FORM_N		1	/* non-print */
#define	FORM_T		2	/* telnet format effectors */
#define	FORM_C		3	/* carriage control (ASA) */

/*
 * Structure codes
 */
#define	STRU_F		1	/* file (no record structure) */
#define	STRU_R		2	/* record structure */
#define	STRU_P		3	/* page structure */

/*
 * Mode types
 */
#define	MODE_S		1	/* stream */
#define	MODE_B		2	/* block */
#define	MODE_C		3	/* compressed */

/*
 * Record Tokens
 */
#define	REC_ESC		'\377'	/* Record-mode Escape */
#define	REC_EOR		'\001'	/* Record-mode End-of-Record */
#define REC_EOF		'\002'	/* Record-mode End-of-File */

/*
 * Block Header
 */
#define	BLK_EOR		0x80	/* Block is End-of-Record */
#define	BLK_EOF		0x40	/* Block is End-of-File */
#define BLK_ERRORS	0x20	/* Block is suspected of containing errors */
#define	BLK_RESTART	0x10	/* Block is Restart Marker */

#define	BLK_BYTECOUNT	2	/* Bytes in this block */
ERR		0x0800
# define RCVINT		0x0400
# define XMITINT	0x0200
# define INITDONE	0x0100
# define INTPENDING	0x0080
# define INTENABLE	0x0040
# define RCVRON		0x0020
# define XMITON		0x0010
# define DEMANDXMIT	0x0008
# define STOPPED	0x0004
# define STARTED	0x0002
# define INITIALIZE	0x0001

/*
 *	ioctl structures for statistics/mode
 */

typedeunix/include/CMC/in.h                                                                                  444     322     145         6371  3621344552   7726                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */


/*
 * Constants and structures defined by the internet system,
 * Per RFC 790, September 1981.
 */

/*
 * Protocols
 */
#define	IPPROTO_ICMP		1		/* control message protocol */
#define	IPPROTO_GGP		2		/* gateway^2 (deprecated) */
#define	IPPROTO_TCP		6		/* tcp */
#define	IPPROTO_PUP		12		/* pup */
#define	IPPROTO_UDP		17		/* user datagram protocol */
#define	IPPROTO_ND		77		/* UNOFFICIAL net disk proto */

#define	IPPROTO_RAW		255		/* raw IP packet */
#define	IPPROTO_MAX		256

/*
 * Port/socket numbers: network standard functions
 */
#define	IPPORT_ECHO		7
#define	IPPORT_DISCARD		9
#define	IPPORT_SYSTAT		11
#define	IPPORT_DAYTIME		13
#define	IPPORT_NETSTAT		15
#define	IPPORT_FTP		21
#define	IPPORT_TELNET		23
#define	IPPORT_SMTP		25
#define	IPPORT_TIMESERVER	37
#define	IPPORT_NAMESERVER	42
#define	IPPORT_WHOIS		43
#define	IPPORT_MTP		57

/*
 * Port/socket numbers: host specific functions
 */
#define	IPPORT_TFTP		69
#define	IPPORT_RJE		77
#define	IPPORT_FINGER		79
#define	IPPORT_TTYLINK		87
#define	IPPORT_SUPDUP		95

/*
 * UNIX TCP sockets
 */
#define	IPPORT_EXECSERVER	512
#define	IPPORT_LOGINSERVER	513
#define	IPPORT_CMDSERVER	514
#define	IPPORT_EFSSERVER	520

/*
 * UNIX UDP sockets
 */
#define	IPPORT_BIFFUDP		512
#d (   (  efine	IPPORT_WHOSERVER	513
#define	IPPORT_ROUTESERVER	520	/* 520+1 also used */

/*
 * Ports < IPPORT_RESERVED are reserved for
 * privileged processes (e.g. root).
 */
#define	IPPORT_RESERVED		1024

/*
 * Link numbers
 */
#define	IMPLINK_IP		155
#define	IMPLINK_LOWEXPER	156
#define	IMPLINK_HIGHEXPER	158

/*
 * Internet address (old style... should be updated)
 */
struct in_addr {
	union {
		struct { uchar s_b1,s_b2,s_b3,s_b4; } S_un_b;
		struct { ushort s_w1,s_w2; } S_un_w;
		ulong S_addr;
	} S_un;
#define	s_addr	S_un.S_addr	/* can be used for most tcp & ip code */
#define	s_host	S_un.S_un_b.s_b2	/* host on imp */
#define	s_net	S_un.S_un_b.s_b1	/* network */
#define	s_imp	S_un.S_un_w.s_w2	/* imp */
#define	s_impno	S_un.S_un_b.s_b4	/* imp # */
#define	s_lh	S_un.S_un_b.s_b3	/* logical host */
};

/*
 * Definitions of bits in internet address integers.
 */
#define	IN_CLASSA(i)		((((long)(i))&0x80000000)==0)
#define	IN_CLASSA_NET		0xff000000
#define	IN_CLASSA_NSHIFT	24
#define	IN_CLASSA_HOST		0x00ffffff

#define	IN_CLASSB(i)		((((long)(i))&0xc0000000)==0x80000000)
#define	IN_CLASSB_NET		0xffff0000
#define	IN_CLASSB_NSHIFT	16
#define	IN_CLASSB_HOST		0x0000ffff

#define	IN_CLASSC(i)		((((long)(i))&0xc0000000)==0xc0000000)
#define	IN_CLASSC_NET		0xffffff00
#define	IN_CLASSC_NSHIFT	8
#define	IN_CLASSC_HOST		0x000000ff

#define	INADDR_ANY	0x00000000

/*
 * Socket address, internet style.
 */
typedef
struct sockaddr_in {
	short	sin_family;
	ushort	sin_port;
	struct	in_addr sin_addr;
	char	sin_zero[8];
} sockaddr_in;

#if !defined(vax)
/*
 * Macros for number representation conversion.
 */
#define	ntohl(x)	(x)
#define	ntohs(x)	(x)
#define	htonl(x)	(x)
#define	htons(x)	(x)
#endif

#ifdef KERNEL
extern	struct domain inetdomain;
extern	struct protosw inetsw[];
#endif
0100
# define INTPENDING	0x0080
# define INTENABLE	0x0040
# define RCVRON		0x0020
# define XMITON		0x0010
# define DEMANDXMIT	0x0008
# define STOPPED	0x0004
# define STARTED	0x0002
# define INITIALIZE	0x0001

/*
 *	ioctl structures for statistics/mode
 */

typedeunix/include/CMC/inet.h                                                                                444     322     145          761  3621344553  10235                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	inet.h	4.1	83/05/28	*/

/*
 * External definitions for
 * functions in inet(3N)
 */
struct	in_addr inet_addr();
char	*inet_ntoa();
struct	in_addr inet_makeaddr();
unsigned long inet_network();
} S_un;
#defineunix/include/CMC/longnames.h                                                                           444     322     145         2712  3621344553  11277                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * This file contains defines to convert long names into names which are
 * unique in the first 7 characters.  This allows systems where the
 * preprocessor handles long names but the compiler doesn't to compile
 * files properly.  If the target system supports long names in the
 * compiler, these defines can be removed.
 *
 * Created August 3, 1984		D. S. Brown, CMC
 */

#define sockaddr_eth sadd_eth
# define sockaddr_in sadd_in

#define inet_addr	in_addr
#define inet_lnaof	in_lnaof
#define inet_makeaddr	in_makeaddr
#define inet_netof	in_netof
#define inet_network	in_network
#define inet_ntoa	in_ntoa

#define gethostbyaddr		gthstbaddr
#define gethostbyname		gthstbname
#define gethostent		gthstent
#define getnetbyaddr		gtnetbaddr
#define getnetbyname		gtnetbname
#define getnetent		gtnetent
#define getprotobyname		gtprbname
#define getprotobynumber	gtprbnumber
#define getprotoent		gtproent
#define getservbyname		gtsrvbname
#define getservbyport		gtsrvbport
#define getservent		gtsrvent

#define gethostname		gthstname
#define gettimeofday		gettod

#define getsockname		gtsoname
#define getpeername		gtprname
#define getsockopt		gtsoopt

#define setsockopt		stsoopt
n_addr sin_addr;
	char	sin_zero[8];
} sockaddr_in;

#iunix/include/CMC/netbfr.h                                                                              444     322     145         2512  3621344554  10573                                                                                                                                                                                                                                                                                                                                                                      /*
 * done processing structure -- managed by bfrdone
 */

typedef struct bdone {
	int		(*b_proc)();
	char		 *b_param;
} BDONE;

#define NDONESTK	4		/* four levels of done processing */

/*
 * The bfr itself
 */

typedef struct bfr {
	struct bfr 	*b_link;		/* the next one */
	unsigned short	 b_flags;		/* Status/flags	*/
	short		 b_len;			/* size of bfr */
	char		*b_addr;		/* bfr place */
	short		 b_msglen;		/* data in bfr */
	short		 b_resv;		/* reserved */
	BDONE		 b_done[NDONESTK];	/* done processing routines */
	short		 b_donesp;		/* index into b_done */
	short		 b_level;		/* curr proto level */
	short		 b_device;		/* current device for bfr */
} BFR;

/*
 *	b_flags -	bits 0-5 used for TCP "t_ctl" bits
 *			bit 6 used for TCP "TCPURGENT" bit
 *			bits 12-15 used for BFR control bits
 */

# define B_NO_REPLACE	0x4000		/* See iftcpinput		*/

/*	b_donesp - default		*/

#define BDEMPTY			-1		/* index zero pops to this */

/*
 * b_level values
 * see protodef.c
 */

#define LINK_LEVEL		0
#define NETWORK_LEVEL		1
#define TRANSPORT_LEVEL		2
#define INTERFACE_LEVEL		3

#define INIT_OPS		256		/* initialize operations */
#define TERM_OPS		257		/* terminate operations */

/*
 * network packets
 */

#define PKTDATASIZE	1514
#define PKTSUMSIZE	4

typedef struct pkt {
	BFR	p_bfr;
	char	p_data[PKTDATASIZE];
	char 	p_checksum[PKTSUMSIZE];
} PKT;
y		gettod

#define getsockname		gtsoname
#define getpeername		gtprname
#define getsockopt		gtsoopt

#define setsockopt		stsoopt
n_addr sin_addr;
	char	sin_zero[8];
} sockaddr_in;

#iunix/include/CMC/netdb.h                                                                               444     322     145         2776  3621344554  10423                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	%M%	%I%	%E%	*/
/*
 * Structures returned by network
 * data base library.  All addresses
 * are supplied in host order, and
 * returned in network order (suitable
 * for use in system calls).
 */
struct	hostent {
	char	*h_name;	/* official name of host */
	char	**h_aliases;	/* alias list */
	int	h_addrtype;	/* host address type */
	int	h_length;	/* length of address */
	char	*h_addr;	/* address */
};

/*
 * Assumption here is that a network number
 * fits in 32 bits -- probably a poor one.
 */
struct	netent {
	char	*n_name;	/* official name of net */
	char	**n_aliases;	/* alias list */
	int	n_addrtype;	/* net address type */
	int	n_net;		/* network # */
};

struct	servent {
	char	*s_name;	/* official service name */
	char	**s_aliases;	/* alias list */
	int	s_port;		/* port # */
	char	*s_proto;	/* protocol to use */
};

struct	protoent {
	char	*p_name;	/* official protocol name */
	char	**p_aliases;	/* alias list */
	int	p_proto;	/* protocol # */
};

struct hostent	*gethostbyname(), *gethostbyaddr(), *gethostent();
struct netent	*getnetbyname(), *getnetbyaddr(), *getnetent();
struct servent	*getservbyname(), *getservbyport(), *getservent();
struct protoent	*getprotobyname(), *getprotobynumber(), *getprotoent();
#iunix/include/CMC/param.h                                                                               444     322     145         1477  3621344555  10425                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * This file defines values used by the networking software which on the
 * standard 4.2 software were picked up out of <sys/param.h>.  Since it
 * is not assured that the values defined in the 4.2 <sys/param (   (  .h> will be
 * in another system's <sys/param.h> file, the values actually needed are
 * supplied in this file.
 *
 * Created September 16, 1984 - Deb Brown, CMC
 */

#define MAXPATHLEN	1024		/* max length of file name */
#define NCARGS		10240		/* # chars in exec arglist */
#define NBBY		8		/* number bits per byte */
fines values used by the networking software which on the
 * standard 4.2 software were picked up out of <sys/param.h>.  Since it
 * is not assured that the values defined in the 4.2 <sys/paramunix/include/CMC/pty.h                                                                                 444     322     145         1460  3621344555  10131                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

# define NPTY 32

# define pt_flags t_tbuf.c_ptr[0]
# define pt_send t_tbuf.c_ptr[1]

/*
 *	Values for pt_flags field
 */

# define PF_PKT		0x1
# define PF_REMOTE	0x2
# define PF_NOSTOP	0x4
# define PF_STOPPED	0x8

/*
 *	Values or'd into PKT mode control byte
 */

# define TIOCPKT_FLUSHREAD	0x1
# define TIOCPKT_FLUSHWRITE	0X2
# define TIOCPKT_STOP		0x4
# define TIOCPKT_START		0x8
# define TIOCPKT_NOSTOP		0x10
# define TIOCPKT_DOSTOP		0x20

# define TIOCPKT (('p'<<8) | 128)
# define TIOCREMOTE (('p'<<8) | 129)
 {
	char	*n_name;	/* official name of net */
	char	**n_aliases;	/* alias list */
	int	n_addrtype;	/* net address type */
	int	n_net;		/* network # */
};

struct	servent {
	char	*s_name;	/* official service naunix/include/CMC/ring.h                                                                                444     322     145         1414  3621344555  10253                                                                                                                                                                                                                                                                                                                                                                      /*
 * data structure for enp and host to asynchrouously communicate
 */

typedef struct RING
{
	short	r_rdidx;
	short	r_wrtidx;
	short	r_size;
	short	r_pad;			/* to make VAXen happy */
	int	r_slot[ 1 ];
}RING;

typedef struct RING4
{
	short	r_rdidx;
	short	r_wrtidx;
	short	r_size;
	short	r_pad;			/* to make VAXen happy */
	int	r_slot[ 4 ];
} RING4;

typedef struct RING8
{
	short	r_rdidx;
	short	r_wrtidx;
	short	r_size;
	short	r_pad;			/* to make VAXen happy */
	int	r_slot[ 8 ];
} RING8;

typedef struct RING16
{
	short	r_rdidx;
	short	r_wrtidx;
	short	r_size;
	short	r_pad;			/* to make VAXen happy */
	int	r_slot[ 16 ];
} RING16;

typedef struct RING32
{
	short	r_rdidx;
	short	r_wrtidx;
	short	r_size;
	short	r_pad;			/* to make VAXen happy */
	int	r_slot[ 32 ];
} RING32;
 define TIOCREMOTE (('p'<<8) | 129)
 {
	char	*n_name;	/* official name of net */
	char	**n_aliases;	/* alias list */
	int	n_addrtype;	/* net address type */
	int	n_net;		/* network # */
};

struct	servent {
	char	*s_name;	/* official service naunix/include/CMC/signal.h                                                                              444     322     145          604  3621344556  10552                                                                                                                                                                                                                                                                                                                                                                      
/*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

# include <signal.h>

# ifndef SIGURGENT
#	define SIGURGENT SIGUSR2
# endif SIGURGENT
x;
	short	r_wrtidx;
	short	r_size;
	short	r_pad;			/* to make VAXen happy */
	int	r_slot[ 8 ];
} RING8;

typedef struct RINGunix/include/CMC/socket.h                                                                              444     322     145         7227  3621344557  10616                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	socket.h	6.1	83/07/29	*/

/*
 * Definitions related to sockets: types, address families, options.
 *
 *	This file should be used be applications wanting to deal
 *	solely with the 4.2 user-level socket operations.
 */

/*
 * Types
 */
#define	SOCK_STREAM	1		/* stream socket */
#define	SOCK_DGRAM	2		/* datagram socket */
#define	SOCK_RAW	3		/* raw-protocol interface */
#define	SOCK_RDM	4		/* reliably-delivered message */
#define	SOCK_SEQPACKET	5		/* sequenced packet stream */

/*
 * Option flags per-socket.
 */
#define	SO_DEBUG	0x01		/* turn on debugging info recording */
#define	SO_ACCEPTCONN	0x02		/* socket has had listen() */
#define	SO_REUSEADDR	0x04		/* allow local address reuse */
#define	SO_KEEPALIVE	0x08		/* keep connections alive */
#define	SO_DONTROUTE	0x10		/* just use interface addresses */
				/* 0x20 was SO_NEWFDONCONN */
#define	SO_USELOOPBACK	0x40		/* bypass hardware when possible */
#define	SO_LINGER	0x80		/* linger on close if data present */
#define	SO_DONTLINGER	(~SO_LINGER)	/* ~SO_LINGER */

/*
 * Address families.
 */
#define	AF_UNSPEC	0		/* unspecified */
#define	AF_UNIX		1		/* local to host (pipes, portals) */
#define	AF_INET		2		/* internetwork: UDP, TCP, etc. */
#define	AF_IMPLINK	3		/* arpanet imp addresses */
#define	AF_PUP		4		/* pup protocols: e.g. BSP */
#define	AF_CHAOS	5		/* mit CHAOS protocols */
#define	AF_NS		6		/* XEROX NS protocols */
#define	AF_NBS		7		/* nbs protocols */
#define	AF_ECMA		8		/* european computer manufacturers */
#define	AF_DATAKIT	9		/* datakit protocols */
#define	AF_CCITT	10		/* CCITT protocols, X.25 etc */
#define	AF_SNA		11		/* IBM SNA */
#define AF_ETHER	12		/* direct Ethernet (2.0) access */

#define	AF_MAX		13

/*
 * Structure used by kernel to store most
 * addresses.
 */
struct sockaddr {
	ushort	sa_family;		/* address family */
	char	sa_data[14];		/* up to 14 bytes of direct address */
};

/*
 * Structure used by kernel to pass protocol
 * information in raw sockets.
 */
struct sockproto {
	ushort	sp_family;		/* address family */
	ushort	sp_protocol;		/* protocol */
};

/*
 * Protocol families, same as address families for now.
 */
#define	PF_UNSPEC	AF_UNSPEC
#define	PF_UNIX		AF_UNIX
#define	PF_INET		AF_INET
#define	PF_IMPLINK	AF_IMPLINK
#define	PF_PUP		AF_PUP
#define	PF_CHAOS	AF_CHAOS
#define	PF_NS		AF_NS
#define	PF_NBS		AF_NBS
#define	PF_ECMA		AF_ECMA
#define	PF_DATAKIT	AF_DATAKIT
#define	PF_CCITT	AF_CCITT
#define	PF_SNA		AF_SNA
#define PF_ETHER	AF_ETHER

#define	PF_MAX		AF_MAX

/*
 * Level number for (get/set)sockopt() to apply to socket itself.
 */
#define	SOL_SOCKET	0xffff		/* options for socket level */

/*
 * Message header for recvmsg and sendmsg calls.
 */
struct msghdr {
	caddr_t	msg_name;		/* optional address */
# define msg_namelen msg_nl
	int	msg_namelen;		/* size of address */
	struct	iovec *msg_iov;		/* scatter/gather array */
	int	msg_iovlen;		/* # elements in msg_iov */
	caddr_t	msg_accrights;		/* access rights sent/received */
# define msg_accrightslen msg_arl
	int	msg_accrightslen;
};

#define	MSG_OOB		0x1		/* process out-of-band data */
#define	MSG_PEEK	0x2		/* peek at incoming message */
#define	MSG_DONTROUTE	0x4		/* send without using routing tables */

#define	MSG_MAXIOVLEN	16

/*
 *	ioctl operations users can apply to sockets
 */

# define mkioctl(type,value) (('type'<<8)|value)

# define SIOCATMARK	mkioctl(S,126)
# define SIOCSPGRP	mkioctl(S,125)
# define SIOCGPGRP	mkioctl(S,124)
orted. */
#define EX_LCOL	0x10	/* A late collision occurred on transmission. */
#define EX_CAR	0x08	/* Carrier was lost during transmission. */
#define EX_RTRY	0x04	/* Retry failure. */
#define EX_MERR	0x02	/* A memory error occured on transmit. */
#define EX_CERR	0x01	/* A collision error was reported. */

#if !defined(vax)
/*
 * Macros for number representaunix/include/CMC/sysdep.h                                                                              444     322     145         1141  3621344557  10622                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * This file contains defines and such that are specific to individual
 * systems.
 *
 * Before including this file, TARGET_SYSTEM should have been #defined
 * to the name of the system we're running on.
 */
 (   (  
/* Target-system specific values follow. */

#if TARGET_SYSTEM == VALID
#define void	int
#endif
ial and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * This file contains defines and such that are specific to individual
 * systems.
 *
 * Before including this file, TARGET_SYSTEM should have been #defined
 * to the name of the system we're running on.
 */
unix/include/CMC/telnet.h                                                                              444     322     145         6746  3621344560  10620                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	telnet.h	4.4	82/03/16	*/
/*
 * Definitions for the TELNET protocol.
 */
#define	IAC	255		/* interpret as command: */
#define	DONT	254		/* you are not to use option */
#define	DO	253		/* please, you use option */
#define	WONT	252		/* I won't use option */
#define	WILL	251		/* I will use option */
#define	SB	250		/* interpret as subnegotiation */
#define	GA	249		/* you may reverse the line */
#define	EL	248		/* erase the current line */
#define	EC	247		/* erase the current character */
#define	AYT	246		/* are you there */
#define	AO	245		/* abort output--but let prog finish */
#define	IP	244		/* interrupt process--permanently */
#define	BREAK	243		/* break */
#define	DM	242		/* data mark--for connect. cleaning */
#define	NOP	241		/* nop */
#define	SE	240		/* end sub negotiation */

#define SYNCH	242		/* for telfunc calls */

/* Telnet options - Names have been truncated to be unique in 7 chars */


#define TO_BINARY	0	/* 8-bit data path */
#define TO_ECHO		1	/* echo */
#define TO_RCP		2	/* prepare to reconnect */
#define TO_SGA		3	/* suppress go ahead */
#define TO_NAMS		4	/* approximate message size */
#define TO_STATUS	5	/* give status */
#define TO_TM		6	/* timing mark */
#define TO_RCTE		7	/* remote controlled transmission and echo */
#define TO_NL 		8	/* negotiate about output line width */
#define TO_NP 		9	/* negotiate about output page size */
#define TO_NCRD		10	/* negotiate about CR disposition */
#define TO_NHTS		11	/* negotiate about horizontal tabstops */
#define TO_NHTD		12	/* negotiate about horizontal tab disposition */
#define TO_NFFD		13	/* negotiate about formfeed disposition */
#define TO_NVTS		14	/* negotiate about vertical tab stops */
#define TO_NVTD		15	/* negotiate about vertical tab disposition */
#define TO_NLFD		16	/* negotiate about output LF disposition */
#define TO_XASCII	17	/* extended ascic character set */
#define TO_LOGOUT	18	/* force logout */
#define TO_BM		19	/* byte macro */
#define TO_DET		20	/* data entry terminal */
#define TO_SUPDUP	21	/* supdup protocol */
#define TO_EXOPL	255	/* extended-options-list */

/* Define (real) long names to be the shorter ones */

#define TELOPT_BINARY	TO_BINARY
#define TELOPT_ECHO	TO_ECHO
#define TELOPT_RCP	TO_RCP
#define TELOPT_SGA	TO_SGA
#define TELOPT_NAMS	TO_NAMS
#define TELOPT_STATUS	TO_STATUS
#define TELOPT_TM	TO_TM
#define TELOPT_RCTE	TO_RCTE
#define TELOPT_NAOL	TO_NL
#define TELOPT_NAOP	TO_NP
#define TELOPT_NAOCRD	TO_NCRD
#define TELOPT_NAOHTS	TO_NHTS
#define TELOPT_NAOHTD	TO_NHTD
#define TELOPT_NAOFFD	TO_NFFD
#define TELOPT_NAOVTS	TO_NVTS
#define TELOPT_NAOVTD	TO_NVTD
#define TELOPT_NAOLFD	TO_NLFD
#define TELOPT_XASCII	TO_XASCII
#define TELOPT_LOGOUT	TO_LOGOUT
#define TELOPT_BM	TO_BM
#define TELOPT_DET	TO_DET
#define TELOPT_SUPDUP	TO_SUPDUP
#define TELOPT_EXOPL	TO_EXOPL

#ifdef TELCMDS
char *telcmds[] = {
	"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
	"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
};
#endif

#ifdef TELOPTS
char *telopts[] = {
	"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
	"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
	"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
	"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
	"DATA ENTRY TERMINAL", "SUPDUP"
};
#endif
n apply to sockets
 */

# unix/include/CMC/tftp.h                                                                                444     322     145         2531  3621344560  10266                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	tftp.h	4.2	83/06/11	*/

/*
 * Trivial File Transfer Protocol (IEN-133)
 */
#define	SEGSIZE		512		/* data segment size */

/*
 * Packet types.
 */
#define	RRQ	01			/* read request */
#define	WRQ	02			/* write request */
#define	DATA	03			/* data packet */
#define	ACK	04			/* acknowledgement */
#define	ERROR	05			/* error code */

struct	tftphdr {
	short	th_opcode;		/* packet type */
	union {
		short	tu_block;	/* block # */
		short	tu_code;	/* error code */
		char	tu_stuff[1];	/* request packet stuff */
	} th_u;
	char	th_data[1];		/* data or error string */
};

#define	th_block	th_u.tu_block
#define	th_code		th_u.tu_code
#define	th_stuff	th_u.tu_stuff
#define	th_msg		th_data

/*
 * Error codes.
 */
#define	EUNDEF		0		/* not defined */
#define	ENOTFOUND	1		/* file not found */
#define	EACCESS		2		/* access violation */
#define	ENOSPACE	3		/* disk full or allocation exceeded */
#define	EBADOP		4		/* illegal TFTP operation */
#define	EBADID		5		/* unknown transfer ID */
#define	EEXISTS		6		/* file already exists */
#define	ENOUSER		7		/* no such user */
 */
#define TO_NAMS		4	/* approximate message size */
#define TO_STATUS	5	/* give status */
#define TO_TM		6	/* timing mark */
#define TO_RCTE		7	/* remote controlled unix/include/CMC/types.h                                                                               444     322     145         1204  3621344561  10452                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

# include <sys/types.h>

typedef	unsigned char	uchar;
typedef	unsigned long	ulong;

typedef unsigned char UCHAR;
typedef unsigned short UINT;
typedef unsigned short u_short;
typedef unsigned char  u_char;
typedef unsigned long  u_long;
typedef UCHAR BYTE;
typedef unsigned short WORD;
typedef unsigned long ULONG;
typedef unsigned long HOST;

tphdr {
	short	th_opcode;		/* packet type */
	union {
		short	tu_block;	/* block # */
		short	tu_code;	/* error code */
		char	tu_stuff[1];	/* request packet stuff */
	} th_u;
	char	th_data[1];		/* data or error string */
};

#define	th_block	th_u.tu_block
#define	th_code		th_u.tu_code
#define	th_stuff	th_u.tu_stuff
#define	th_msg		th_data

/*
 * Error codes.
 */
#define	EUNDEFunix/include/CMC/user_socket.h                                                                         444     322     145         3235  3621344561  11642                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	User-level information for dealing with the CMC socket
 *	emulation driver.
 *
 *	This file should be included by applications that want
 *	access to the socket mechanism without using the 4.2
 *	user-level entries.  In general, that should only be
 *	library-type routines seeking to emulate a 4.2 function.
 */

typedef
struct userparm {
	char	*p_where;
	long	 p_len;
	char	*p_where2;
	long	 p_len2;
	char	*p_where3;
	long	 p_len3;
} userparm;

# ifndef KERNEL
# define NSOCKETS 256
# endif

# define mkioctl(type,value) (('type'<<8)|value)
# define SIOCBIND mkioctl(S,1)
# define SIOCLISN mkioctl(S,2)
# define SIOCCONN mkioctl(S,3)
# define SIOCRESV mkioctl(S,4)
# define SIOCACPT mkioctl(S,5)
# define SIOCRECV mkioctl(S,6)
# define SIOCSEND mkioctl(S,7)
# define SIOCGNAM mkioctl(S,8)
# define SIOCSOPT mkioctl(S,9)
# define SIOCGOPT mkioctl(S,10)
# define SIOCSHUT mkioctl(S,11)
# define SIOCSENDTO mkioctl(S,12)
# define SIOCRECVFROM mkioctl(S,13)

/*
 *	User-visible ioctl's
 */

# define SIOCATMARK mkioctl(S,126)
# define SIOCSPGRP  mkioctl(S,125)
# define SIOCGPGRP  mkioctl(S,124)

/*
 *	For "generic" socket names - as used by sock_driver
 *	and related routines.
 *	I_NET Guys will cast as sockaddr_in
 *	ETH_NET G (   (  uys will cast as sockaddr_eth
 */

typedef struct	sockaddr {
	ushort	sa_family;		/* Protocol family	*/
	char	sa_data[14];		/* Generic "name"	*/
} sockaddr;

 Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	User-level information for dealing with the CMC socket
 *	emulation driver.
 *
 *	This file should be included by applications that want
 *	access to the socket mechanism without using the 4.2
 *	user-leveunix/include/README                                                                                    440     322     145          646  3621344562   7401                                                                                                                                                                                                                                                                                                                                                                      	The subdirectory CMC contains the include files used by the
routines in ../lib.  All the Makefiles included with the CMC distribution
reference this directory via the -I flag to cc; however the kernel
resident code makes references of the form
#include <CMC/...>

	To avert potential problems, it is most prudent to copy
the CMC directory to /usr/include; the Makefile in this directory
does that when told
	make install
pplications that want
 *	access to the socket mechanism without using the 4.2
 *	user-leveunix/lib/                                                                                              750     322     145            0  3646057540   5576                                                                                                                                                                                                                                                                                                                                                                      unix/lib/README                                                                                        444     322     145         2021  3621344563   6536                                                                                                                                                                                                                                                                                                                                                                      
	These files provide interfaces to the network device driver,
to the several network data bases, and utilities to manipulate Internet
addresses.

	We normally collect these together into a library called
"libcmcnet.a" and invoked by passing "-lcmcnet" to the linker "ld".
Several of the Makefiles presume such an organization, but you could
just as easily install all this into the normal C library.

	Following is the ordering for libcmcnet.a, useful if you
don't have ranlib(1) or if lorder(1) and tsort(1) don't work any
better on your system than they do on ours.
	rcmd.o
	connect.o
	gethostbyadd.o
	getnetbyaddr.o
	getnetbyname.o
	getnetent.o
	getproto.o
	getprotoname.o
	getprotoent.o
	getservbynam.o
	getservbypor.o
	getservent.o
	inet_lnaof.o
	inet_makeadd.o
	inet_netof.o
	inet_network.o
	inet_ntoa.o
	accept.o
	getpeername.o
	bind.o
	gethostbynam.o
	gethostent.o
	inet_addr.o
	listen.o
	sockopt.o
	shutdown.o
	socket.o
	gethostname.o
	opendir.o
	readdir.o
	ruserpass.o
	send.o
	recv.o
	net_error.o
	perror.o
	sendto.o
	recvfrom.o
ine SIOCSEND mkioctl(S,7)
# define SIOCGNAM mkioctl(S,8)
# define SIOCSOPT mkioctl(S,9)
# define SIOCGOPT mkioctl(S,10)
# define SIOCSHUT mkioctl(S,11)
# define SIOCSENDTO mkioctl(S,12)
# define SIOCRECVFROM mkioctl(S,13)

/*
 *	User-visible ioctl's
 */

# define SIOCATMARK mkioctl(S,126)
# define SIOCSPGRP  mkioctl(S,125)
# define SIOCGPGRP  mkioctl(S,124)

/*
 *	For "generic" socket names - as used by sock_driver
 *	and related routines.
 *	I_NET Guys will cast as sockaddr_in
 *	ETH_NET Gunix/lib/accept.c                                                                                      444     322     145         2061  3621344563   7265                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding July 1984 by John Mullen
 */

# include <CMC/longnames.h>
# include <CMC/types.h>
# include <CMC/user_socket.h>
# include <CMC/errno.h>

# define SOCKBASE "/dev/socket/s%d"

accept (s, name, namelen)
char *name, *namelen;
{
	register int fid;

	fid = opensock ();
	if (fid >= 0) {
		if (ioctl (s, SIOCACPT, fid) < 0) {
			close (fid);
			return (-1);
		}
		getpeername (fid, name, namelen);
	}
	return (fid);
}

static
opensock ()
{
	char sockname[32];
	register short i;
	register int fd;
	extern errno;

	for (i = NSOCKETS; i > 0; i--) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd >= 0)
			return (fd);
		if (errno == ENOENT)
			i = i/2 +1 +1;
	}
		
	errno = ENOBUFS;
	return (-1);
}
ne SIOCGNAM mkioctl(S,8)
# define SIOCSOPT mkioctl(S,9)
# define SIOCGOPT mkioctl(S,10)
# define SIOCSHUT mkioctl(S,11)
# define SIOCSENDTO mkioctl(S,12)
# define SIOCRECVFROM mkioctl(S,13)

/*
 *	User-visible ioctl's
 */

# define SIOCATMARK mkioctl(S,126)
# define SIOCSPGRP  mkioctl(S,125)
# define SIOCGPGRP  mkioctl(S,124)

/*
 *	For "generic" socket names - as used by sock_driver
 *	and related routines.
 *	I_NET Guys will cast as sockaddr_in
 *	ETH_NET Gunix/lib/bind.c                                                                                        444     322     145         1156  3621344564   6747                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding July 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>

bind (s, name, namelen)
char *name;
{
	userparm pblock;
	register userparm *pb = &pblock;

	pb->p_where = name;
	pb->p_len = namelen;

	if (ioctl (s, SIOCBIND, pb) < 0)
		return (-1);
	else	return (0);
}

tl (s, SIOCACPT, fid) < 0) {
			close (fid);
			return (-1);
		}
		getpeername (fid, name, namelen);
	}
	return (fid);
}

static
opensock ()
{
	char sockname[32];
	register short i;
	register int fd;
	extern errno;

	for (i = NSOCKETS; i > 0; i--) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd >= 0)
			return (fd);
		if (errno == ENOENT)
			i = i/unix/lib/connect.c                                                                                     444     322     145         1470  3621344564   7463                                                                                                                                                                                                                                                                                                                                                                      
/*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	This file implements the semantics of the 4.2BSD 
 *	"connect" system call. The "socket descriptor" passed
 *	as the first parameter to this routine must have been
 *	obtained from a call to "socket".
 */

/*	HISTORY:
 *		initial coding July 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>

connect (s, name, namelen)
char *name;
{
	userparm pb;
	register userparm *p = &pb;

	p->p_len = namelen;
	p->p_where = name;
	if (ioctl (s, SIOCCONN, p) < 0)
		return (-1);
	else	return (0);
}
xtern errno;

	for (i = NSOCKETS; i > 0; i--) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd >= 0)
			return (fd);
		if (errno == ENOENT)
			i = i/unix/lib/getcwd.c                                                                                      444     322     145         2214  3621344565   7305                                                                                                                                                                                                                                                                                                                                                                      /*	@(#)getcwd.c	1.2	*/
/*LINTLIBRARY*/
/*
 * Library routine to GET the Current Working Directory.
 * arg1 is a pointer to a character buffer into which the
 * path name of the current directory is placed by the
 * subroutine.  arg1 may be zero, in which case the 
 * subroutine will call malloc to get the required space.
 * arg2 is the length of the buffer space for the path-name.
 * If the actual path-name is longer than (arg2-2), or if
 * the value of arg2 is not at least 3, the subroutine will
 * return  (   (  a value of zero, with errno set as appropriate.
 */

#include <stdio.h>
#include <sys/errno.h>

extern FILE *popen();
extern char *malloc(), *fgets(), *strchr();
extern int errno, pclose();

char *
getcwd(arg1, arg2)
char	*arg1;
int	arg2;
{
	FILE	*pipe;
	char	*trm;

	if(arg2 == 0) {
		errno = EINVAL;
		return(0);
	}
	if(arg1 == 0)
		if((arg1 = malloc((unsigned)arg2)) == 0) {
			errno = ENOMEM;
			return(0);
		}
	errno = 0;
	if((pipe = popen("pwd", "r")) == 0)
		return(0);
	(void) fgets(arg1, arg2, pipe);
	(void) pclose(pipe);
	trm = strchr(arg1, '\0');
	if(*(trm-1) != '\n') {
		errno = ERANGE;
		return(0);
	}
	*(trm-1) = '\0';
	return(arg1);
}
len)
char *name;
{
	userparm pb;
	register userparm *p = &pb;

	p->p_len = namelen;
	p->p_where = name;
	if (ioctl (s, SIOCCONN, p) < 0)
		return (-1);
	else	return (0);
}
xtern errno;

	for (i = NSOCKETS; i > 0; i--) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd >= 0)
			return (fd);
		if (errno == ENOENT)
			i = i/unix/lib/gethostbyadd.c                                                                                444     322     145         1300  3621344565  10504                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	gethostbyaddr.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct hostent *
gethostbyaddr(addr, len, type)
	char *addr;
	register int len, type;
{
	register struct hostent *p;

	sethostent(0);
	while (p = gethostent()) {
		if (p->h_addrtype != type || p->h_length != len)
			continue;
		if (memcmp(p->h_addr, addr, len) == 0)
			break;
	}
	endhostent();
	return (p);
}
*p = &pb;

	p->p_len = namelen;
	p->p_where = name;
	if (ioctl (s, SIOCCONN, p) < 0)
		return (-1);
	else	return (0);
}
xtern errno;

	for (i = NSOCKETS; i > 0; i--) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd >= 0)
			return (fd);
		if (errno == ENOENT)
			i = i/unix/lib/gethostbynam.c                                                                                444     322     145         1324  3621344566  10536                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	gethostbyname.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct hostent *
gethostbyname(name)
	register char *name;
{
	register struct hostent *p;
	register char **cp;

	sethostent(0);
	while (p = gethostent()) {
		if (strcmp(p->h_name, name) == 0)
			break;
		for (cp = p->h_aliases; *cp != 0; cp++)
			if (strcmp(*cp, name) == 0)
				goto found;
	}
found:
	endhostent();
	return (p);
}
 = namelen;
	p->p_where = name;
	if (ioctl (s, SIOCCONN, p) < 0)
		return (-1);
	else	return (0);
}
xtern errno;

	for (i = NSOCKETS; i > 0; i--) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd >= 0)
			return (fd);
		if (errno == ENOENT)
			i = i/unix/lib/gethostent.c                                                                                  444     322     145         4114  3621344566  10216                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	gethostent.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <stdio.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <CMC/netdb.h>
#include <ctype.h>

/*
 * Internet version.
 */
#define	MAXALIASES	35
#define	MAXADDRSIZE	14

static char HOSTDB[] = "/etc/hosts";
static FILE *hostf = NULL;
static char line[BUFSIZ+1];
static char hostaddr[MAXADDRSIZE];
static struct hostent host;
static char *host_aliases[MAXALIASES];
static int stayopen = 0;
static char *any();

sethostent(f)
	int f;
{
	if (hostf == NULL)
		hostf = fopen(HOSTDB, "r" );
	else
		rewind(hostf);
	stayopen |= f;
}

endhostent()
{
	if (hostf && !stayopen) {
		fclose(hostf);
		hostf = NULL;
	}
}

struct hostent *
gethostent()
{
	char *p;
	register char *cp, **q;

	if (hostf == NULL && (hostf = fopen(HOSTDB, "r" )) == NULL)
		return (NULL);
again:
	if ((p = fgets(line, BUFSIZ, hostf)) == NULL)
		return (NULL);
	if (*p == '#')
		goto again;
	cp = any(p, "#\n");
	if (cp == NULL)
		goto again;
	*cp = '\0';
	cp = any(p, " \t");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	/* THIS STUFF IS INTERNET SPECIFIC */
	host.h_addr = hostaddr;
	*((u_long *)host.h_addr) = inet_addr(p);
	host.h_length = sizeof (u_long);
	host.h_addrtype = AF_INET;
	while (*cp == ' ' || *cp == '\t')
		cp++;
	host.h_name = cp;
	q = host.h_aliases = host_aliases;
	cp = any(cp, " \t");
	if (cp != NULL) 
		*cp++ = '\0';
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q < &host_aliases[MAXALIASES - 1])
			*q++ = cp;
		cp = any(cp, " \t");
		if (cp != NULL)
			*cp++ = '\0';
	}
	*q = NULL;
	return (&host);
}

static char *
any(cp, match)
	register char *cp;
	char *match;
{
	register char *mp, c;

	while (c = *cp) {
		for (mp = match; *mp; mp++)
			if (*mp == c)
				return (cp);
		cp++;
	}
	return ((char *)0);
}
ne TO_XASCII	17	/* extended ascic character set */
#define TO_LOGOUT	18	/* force logout */
#define TO_BM		19	/* byte macro */
#define TO_DET		20	/* data entry terminal */
#define TO_SUPDUP	21	/* supdup protocol */
#define TO_EXOPL	255	/* extended-options-list */

/* Define (real) long names to be the shorter ones */

#define TELOPT_BINARY	TO_BINARY
#define TELOPT_ECHO	TO_ECHO
#define TELOPT_RCP	TO_RCP
#define TELOPT_SGA	TO_SGA
#defiunix/lib/gethostname.c                                                                                 444     322     145         2075  3621344567  10355                                                                                                                                                                                                                                                                                                                                                                      /*
 * Supplies the function provided by the gethostname system call on
 * 4.2 systems.
 *
 * gethostname (name, lth)
 * char *name;
 * int lth;
 *
 * Gets the host name from the system file /etc/HOST.
 *
 * Initial coding - 24 August 1984 - Deb Brown, CMC
 */

#include <CMC/longnames.h>
#include <sys/utsname.h>

#define HOSTFILE	"/etc/host"
#define READ		0
#define BLANK		040

gethostname (name, lth)
register char *name;
register int lth;
{
struct utsname sysname;
int fid;
int l;

/* First try to get name from the system. */

	if ((uname (&sysname) != -1) && sysname.nodename[0])
	{
		l = lth < sizeof (sysname.nodename) ?
			 lth : sizeof (sysname.nodename);
		memcpy (name, sysname.nodename, l);
		if (l < lth)
			memset (&(name[l]), '\0', lth-l);
		return (0);
	}

/* If that didn't work, read system name from known file */

	fid = open (HOSTFILE, READ);
	if (fid < 0)
	{
		name [0] = 0;
		return (-1);
	}
	l = read (fid, name, lth);
	if (l <= 0)
		*name = 0;
	else
	{
		for (; name [--l] <= BLANK;);
		++l;
		memset (&(name[l]), '\0', lth-l);
	}
	close (fid);
	return (0);
}
 fopen(HOSTDB, "r" )) == NULL)
		return (NULL);
again:
	if ((p = fgets(line, BUFSIZ, hostf)) == NULL)
		return (NULL);
	if (*p == '#')
		goto again;
	cp = any(p, "#\n");
	if (cp == NULL)
		goto again;
	*cp = '\0';
	cp = any(p, " \t");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	/* THIS STUFF IS INTERNET SPECIFIC */
	host.h_addr = hostaddr;
	*((u_long *)host.h_addr) = inet_addr(p);
	host.h_length = sizeof (u_long);
	host.h_addrtype = AF_INET;
	wunix/lib/getnetbyaddr.c                                                                                444     322     145         1150  3621344567  10504                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getnetbyaddr.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct netent *
getnetbyaddr(net, type)
	register int net, type;
{
	register struct netent *p;

	setnetent(0);
	while ( (   (  p = getnetent())
		if (p->n_addrtype == type && p->n_net == net)
			break;
	endnetent();
	return (p);
}
 information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getnetbyaddr.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct netent *
getnetbyaddr(net, type)
	register int net, type;
{
	register struct netent *p;

	setnetent(0);
	while (unix/lib/getnetbyname.c                                                                                444     322     145         1315  3621344570  10507                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getnetbyname.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct netent *
getnetbyname(name)
	register char *name;
{
	register struct netent *p;
	register char **cp;

	setnetent(0);
	while (p = getnetent()) {
		if (strcmp(p->n_name, name) == 0)
			break;
		for (cp = p->n_aliases; *cp != 0; cp++)
			if (strcmp(*cp, name) == 0)
				goto found;
	}
found:
	endnetent();
	return (p);
}

			memset (&(name[l]), '\0', lth-l);
		return (0);
	}

/* If that didn't work, read system name from known file */

	fid = open (HOSTFILE, READ);
	if (fid < 0)
	{
		name [0] = 0;
		return (-1);
	}
	l = read (fid, name, lth);
	if (l <= 0)
		*name = 0;
	else
	{
		for (; name [--l] <= BLANK;);
		++l;
		memseunix/lib/getnetent.c                                                                                   444     322     145         3611  3621344570  10023                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getnetent.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <stdio.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <CMC/netdb.h>
#include <ctype.h>

#define	MAXALIASES	35

static char NETDB[] = "/etc/networks";
static FILE *netf = NULL;
static char line[BUFSIZ+1];
static struct netent net;
static char *net_aliases[MAXALIASES];
static int stayopen = 0;
static char *any();

setnetent(f)
	int f;
{
	if (netf == NULL)
		netf = fopen(NETDB, "r" );
	else
		rewind(netf);
	stayopen |= f;
}

endnetent()
{
	if (netf && !stayopen) {
		fclose(netf);
		netf = NULL;
	}
}

struct netent *
getnetent()
{
	char *p;
	register char *cp, **q;

	if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL)
		return (NULL);
again:
	p = fgets(line, BUFSIZ, netf);
	if (p == NULL)
		return (NULL);
	if (*p == '#')
		goto again;
	cp = any(p, "#\n");
	if (cp == NULL)
		goto again;
	*cp = '\0';
	net.n_name = p;
	cp = any(p, " \t");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	while (*cp == ' ' || *cp == '\t')
		cp++;
	p = any(cp, " \t");
	if (p != NULL)
		*p++ = '\0';
	net.n_net = inet_network(cp);
	net.n_addrtype = AF_INET;
	q = net.n_aliases = net_aliases;
	if (p != NULL) 
		cp = p;
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q < &net_aliases[MAXALIASES - 1])
			*q++ = cp;
		cp = any(cp, " \t");
		if (cp != NULL)
			*cp++ = '\0';
	}
	*q = NULL;
	return (&net);
}

static char *
any(cp, match)
	register char *cp;
	char *match;
{
	register char *mp, c;

	while (c = *cp) {
		for (mp = match; *mp; mp++)
			if (*mp == c)
				return (cp);
		cp++;
	}
	return ((char *)0);
}
 *
any(cp, match)
	register char *cp;
	char *match;
{
	register char *mp, c;

	while (c = *cp) {
		for (mp = match; *mpunix/lib/getpeername.c                                                                                 444     322     145         1732  3621344571  10325                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

# include <CMC/longnames.h>
# include <CMC/types.h>
# include <CMC/user_socket.h>

getpeername (s, name, namelen)
char *name;
int  *namelen;
{
	userparm pblock;
	register userparm *p = &pblock;

	p->p_where = 0;
	p->p_len = 0;
	p->p_where2 = name;
	p->p_len2 = (int) namelen;	/* NOTE nonstandard use of p_len2 */

	if ( ioctl (s, SIOCGNAM, p) < 0 )
		return (-1);
	else	return (0);
}

getsockname (s, name, namelen)
char *name;
int  *namelen;
{
	userparm pblock;
	register userparm *p = &pblock;

	p->p_where = name;
	p->p_len = (int) namelen;	/* NOTE nonstandard use of p_len */
	p->p_where2 = 0;
	p->p_len2 = 0;

	if ( ioctl (s, SIOCGNAM, p) < 0 )
		return (-1);
	else	return (0);
}
pen(NETDB, "r" )) == NULL)
		return (Nunix/lib/getproto.c                                                                                    444     322     145         1124  3621344571   7667                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getproto.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct protoent *
getprotobynumber(proto)
	register int proto;
{
	register struct protoent *p;

	setprotoent(0);
	while (p = getprotoent())
		if (p->p_proto == proto)
			break;
	endprotoent();
	return (p);
}
 use of p_len2 */

	if ( ioctl (s, SIOCGNAM, p) < 0 )
		return (-1);
	else	return (0);
}

getsockname (s, name, namelen)
char *name;
int  *namelen;
{
	userparm pblock;
	register userparm *p = &pblock;

	p->p_where = name;
	p->p_len = (int) namelen;	/* NOTE nonstandard use of p_len */
	p->p_where2 = 0;
	p->p_len2 = 0;

	if ( ioctl (s, SIOCGNAM, p) < 0 )
		return (-1);
	else	return (0);
}
pen(NETDB, "r" )) == NULL)
		return (Nunix/lib/getprotoent.c                                                                                 444     322     145         3655  3621344572  10412                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getprotoent.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <stdio.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <CMC/netdb.h>
#include <ctype.h>

#define	MAXALIASES	35

static char PROTODB[] = "/etc/protocols";
static FILE *protof = NULL;
static char line[BUFSIZ+1];
static struct protoent proto;
static char *proto_aliases[MAXALIASES];
static int stayopen = 0;
static char *any();

setprotoent(f)
	int f;
{
	if (protof == NULL)
		protof = fopen(PROTODB, "r" );
	else
		rewind(protof);
	stayopen |= f;
}

endprotoent()
{
	if (protof && !stayopen) {
		fclose(protof);
		protof = NULL;
	}
}

struct protoent *
getprotoent()
{
	char *p;
	register char *cp, **q;

	if (protof == NULL && (protof = fopen(PROTODB, "r" )) == NULL)
		return (NULL);
again:
	if ((p = fgets(line, BUFSIZ, protof)) == NULL)
		return (NULL);
	if (*p == '#')
		goto again;
	cp = any(p, "#\n");
	if (cp == NULL)
		goto again;
	*cp = '\0';
	proto.p_name = p;
	cp = any(p, " \t");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	while (*cp == ' ' || *cp == '\t')
		cp++;
	p = any(cp, " \t");
	if (p != NULL)
		*p++ = '\0';
	proto.p_proto = atoi(cp);
	q = proto.p_aliases = proto_aliases;
	if (p != NULL) {
		cp = p;
		while (cp && *cp) {
			if (*cp == ' ' || *cp == '\t') {
				cp++;
				continue;
			}
			if (q < &proto_aliases[MAXALIASES - 1])
				*q++ = cp;
			cp = any(cp, " \t");
			if (cp != NULL)
				*cp++ = '\0';
		}
	}
	*q = NULL;
	return (&proto);
}

static char *
any(cp, match)
	register char *cp;
	char *match;
{
	register char *mp, c;

	while (c = *cp) {
		for (mp = match; *mp; mp++)
			if (*mp == c)
				return (cp);
		cp++;
	}
	return ((char *)0);
}
;
	char *match;
{
	register char *mp, c;

	while (c = *cp) {
		for (mp = match; *mp (   (  unix/lib/getprotoname.c                                                                                444     322     145         1332  3621344572  10532                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getprotoname.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct protoent *
getprotobyname(name)
	register char *name;
{
	register struct protoent *p;
	register char **cp;

	setprotoent(0);
	while (p = getprotoent()) {
		if (strcmp(p->p_name, name) == 0)
			break;
		for (cp = p->p_aliases; *cp != 0; cp++)
			if (strcmp(*cp, name) == 0)
				goto found;
	}
found:
	endprotoent();
	return (p);
}
int f;
{
	if (protof == NULL)
		protof = fopen(PROTODB, "r" );
	else
		rewind(protof);
	stayopen |= f;
}

endprotoent()
{
	if (protof && !stayopen) {
		fclose(protof);
		protof = NULL;
	}
}

struct protoent *
getprotoent()
{
	char *p;
	register char *cp, **q;

	if (protof == NULL && (protof = unix/lib/getservbynam.c                                                                                444     322     145         1453  3621344573  10541                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getservbyname.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct servent *
getservbyname(name, proto)
	char *name, *proto;
{
	register struct servent *p;
	register char **cp;

	setservent(0);
	while (p = getservent()) {
		if (strcmp(name, p->s_name) == 0)
			goto gotname;
		for (cp = p->s_aliases; *cp; cp++)
			if (strcmp(name, *cp) == 0)
				goto gotname;
		continue;
gotname:
		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
			break;
	}
	endservent();
	return (p);
}
tof);
	stayopen |= f;
}

endprotoent()
{
	if (protof && !stayopen) {
		fclose(protof);
		protof = NULL;
	}
}

struct protoent *
getprotoent()
{
	char *p;
	register char *cp, **q;

	if (protof == NULL && (protof = unix/lib/getservbypor.c                                                                                444     322     145         1240  3621344573  10560                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getservbyport.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <CMC/netdb.h>

struct servent *
getservbyport(port, proto)
	int port;
	char *proto;
{
	register struct servent *p;

	setservent(0);
	while (p = getservent()) {
		if (p->s_port != port)
			continue;
		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
			break;
	}
	endservent();
	return (p);
}
= 0)
				goto gotname;
		continue;
gotname:
		if (proto == 0 || strcmp(p->s_proto, proto) == 0)
			break;
	}
	endservent();
	return (p);
}
tof);
	stayopen |= f;
}

endprotoent()
{
	if (protof && !stayopen) {
		fclose(protof);
		protof = NULL;
	}
}

struct protoent *
getprotoent()
{
	char *p;
	register char *cp, **q;

	if (protof == NULL && (protof = unix/lib/getservent.c                                                                                  444     322     145         3734  3621344574  10226                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	getservent.c	5.0	(CMC)	8/24/84		*/

#include <CMC/longnames.h>
#include <stdio.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <CMC/netdb.h>
#include <ctype.h>
#include <CMC/in.h>

#define	MAXALIASES	35

static char SERVDB[] = "/etc/services";
static FILE *servf = NULL;
static char line[BUFSIZ+1];
static struct servent serv;
static char *serv_aliases[MAXALIASES];
static int stayopen = 0;
static char *any();

setservent(f)
	int f;
{
	if (servf == NULL)
		servf = fopen(SERVDB, "r" );
	else
		rewind(servf);
	stayopen |= f;
}

endservent()
{
	if (servf && !stayopen) {
		fclose(servf);
		servf = NULL;
	}
}

struct servent *
getservent()
{
	char *p;
	register char *cp, **q;

	if (servf == NULL && (servf = fopen(SERVDB, "r" )) == NULL)
		return (NULL);
again:
	if ((p = fgets(line, BUFSIZ, servf)) == NULL)
		return (NULL);
	if (*p == '#')
		goto again;
	cp = any(p, "#\n");
	if (cp == NULL)
		goto again;
	*cp = '\0';
	serv.s_name = p;
	p = any(p, " \t");
	if (p == NULL)
		goto again;
	*p++ = '\0';
	while (*p == ' ' || *p == '\t')
		p++;
	cp = any(p, ",/");
	if (cp == NULL)
		goto again;
	*cp++ = '\0';
	serv.s_port = htons((u_short)atoi(p));
	serv.s_proto = cp;
	q = serv.s_aliases = serv_aliases;
	cp = any(cp, " \t");
	if (cp != NULL)
		*cp++ = '\0';
	while (cp && *cp) {
		if (*cp == ' ' || *cp == '\t') {
			cp++;
			continue;
		}
		if (q < &serv_aliases[MAXALIASES - 1])
			*q++ = cp;
		cp = any(cp, " \t");
		if (cp != NULL)
			*cp++ = '\0';
	}
	*q = NULL;
	return (&serv);
}

static char *
any(cp, match)
	register char *cp;
	char *match;
{
	register char *mp, c;

	while (c = *cp) {
		for (mp = match; *mp; mp++)
			if (*mp == c)
				return (cp);
		cp++;
	}
	return ((char *)0);
}
e (c = *cp) {
		for (mp = match; *mpunix/lib/inet_addr.c                                                                                   444     322     145         4201  3621344575   7760                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	inet_addr.c	5.0	(CMC)	8/25/84	*/

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <ctype.h>
#include <CMC/in.h>

/*
 * Internet address interpretation routine.
 * All the network library routines call this
 * routine to interpret entries in the data bases
 * which are expected to be an address.
 * The value returned is in network order.
 */
u_long
inet_addr(cp)
	register char *cp;
{
	register u_long val, base, n;
	register char c;
	u_long parts[4], *pp = parts;

again:
	/*
	 * Collect number up to ``.''.
	 * Values are specified as for C:
	 * 0x=hex, 0=octal, other=decimal.
	 */
	val = 0; base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) {
		if (isdigit(c)) {
			val = (val * base) + (c - '0');
			cp++;
			continue;
		}
		if (base == 16 && isxdigit(c)) {
			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
			cp++;
			continue;
		}
		break;
	}
	if (*cp == '.') {
		/*
		 * Internet format:
		 *	a.b.c.d
		 *	a.b.c	(with c treated as 16-bits)
		 *	a.b	(with b treated as 24 bits)
		 */
		if (pp >= parts + 4)
			return (-1);
		*pp++ = val, cp++;
		goto again;
	}
	/*
	 * Check for trailing characters.
	 */
	if (*cp && !isspace(*cp))
		return (-1);
	*pp++ = val;
	/*
	 * Concoct the address according to
	 * the number of parts specified.
	 */
	n = pp - parts;
	switch (n) {

	case 1:				/* a -- 32 bits */
		val = parts[0];
		break;

	case 2:				/* a.b -- 8.24 bits */
		val = (parts[0] << 24) | (parts[1] & 0xffffff);
		break;

	case 3:				/* a.b.c -- 8.8.16 bits */
		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
			(parts[2] & 0xffff);
		break;

	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
		      ((parts[2] & 0xff) << 8) | (parts[3] & 0xff);
		break;

	default:
		return (-1);
	}
	val = htonl(val);
	return (val);
}
efine TO_LOGOUT	18	/* force logout */
#define TO_BM		19	/* byte macro */
#define TO_DET		20	/* data entry terminal */
#define TO_SUPDUP	21	/* supdup protocol */
#define TO_EXOPL	255	/* extended-options-list */

/* Define (real) long names to be the shorter ones */

#define TELOPT_BINARY	TO_BINARY
#define TELOPT_ECHO	TO_ECHO
#define TELOPT_RCP	TO_RCP
#define TELOPT_SGA	TO_SGA
#defi (   (  unix/lib/inet_lnaof.c                                                                                  444     322     145         1364  3621344575  10154                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	inet_lnaof.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/in.h>

/*
 * Return the local network address portion of an
 * internet address; handles class a/b/c network
 * number formats.
 */
inet_lnaof(in)
	struct in_addr in;
{
	register u_long i = ntohl(in.s_addr);

	if (IN_CLASSA(i))
		return ((i)&IN_CLASSA_HOST);
	else if (IN_CLASSB(i))
		return ((i)&IN_CLASSB_HOST);
	else
		return ((i)&IN_CLASSC_HOST);
}
g parts[4], *pp = parts;

again:
	/*
	 * Collect number up to ``.''.
	 * Values are specified as for C:
	 * 0x=hex, 0=octal, other=decimal.
	 */
	val = 0; base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) unix/lib/inet_makeadd.c                                                                                444     322     145         1512  3621344576  10437                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	inet_makeaddr.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/in.h>

/*
 * Formulate an Internet address from network + host.  Used in
 * building addresses stored in the ifnet structure.
 */
struct in_addr
inet_makeaddr(net, host)
	int net, host;
{
	u_long addr;

	if (net < 128)
		addr = (net << IN_CLASSA_NSHIFT) | host;
	else if (net < 65536)
		addr = (net << IN_CLASSB_NSHIFT) | host;
	else
		addr = (net << IN_CLASSC_NSHIFT) | host;
	addr = htonl(addr);
	return (*(struct in_addr *)&addr);
}
ecified as for C:
	 * 0x=hex, 0=octal, other=decimal.
	 */
	val = 0; base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) unix/lib/inet_netof.c                                                                                  444     322     145         1430  3621344576  10163                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	inet_netof.c	5.0	(CMC)	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/in.h>

/*
 * Return the network number from an internet
 * address; handles class a/b/c network #'s.
 */
inet_netof(in)
	struct in_addr in;
{
	register u_long i = ntohl(in.s_addr);

	if (IN_CLASSA(i))
		return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
	else if (IN_CLASSB(i))
		return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
	else
		return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
}
tonl(addr);
	return (*(struct in_addr *)&addr);
}
ecified as for C:
	 * 0x=hex, 0=octal, other=decimal.
	 */
	val = 0; base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) unix/lib/inet_network.c                                                                                444     322     145         2465  3621344577  10553                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	@(#)inet_network.c	5.0	(CMC)	5.0	8/24/84	*/

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <ctype.h>

/*
 * Internet network address interpretation routine.
 * The library routines call this routine to interpret
 * network numbers.
 */
u_long
inet_network(cp)
	register char *cp;
{
	register u_long val, base, n;
	register char c;
	u_long parts[4], *pp = parts;
	register int i;

again:
	val = 0; base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) {
		if (isdigit(c)) {
			val = (val * base) + (c - '0');
			cp++;
			continue;
		}
		if (base == 16 && isxdigit(c)) {
			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
			cp++;
			continue;
		}
		break;
	}
	if (*cp == '.') {
		if (pp >= parts + 4)
			return (-1);
		*pp++ = val, cp++;
		goto again;
	}
	if (*cp && !isspace(*cp))
		return (-1);
	*pp++ = val;
	n = pp - parts;
	if (n > 4)
		return (-1);
	for (val = 0, i = 0; i < n; i++) {
		val <<= 8;
		val |= parts[i] & 0xff;
	}
	return (val);
}
ts)
		 *	a.b	(with b treated as 24 bits)
		 */
		if (pp >= parts + 4)
			return (-1);
		*pp++ = val, cp++;
		goto again;
	}
	/*
	 * Check for trailing characters.
	 */
	if (*cp && !isspace(*cp))
		returnunix/lib/inet_ntoa.c                                                                                   444     322     145         1311  3621344577  10010                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	inet_ntoa.c	5.0	(CMC)	8/24/84		*/

/*
 * Convert network-format internet address
 * to base 256 d.d.d.d representation.
 */
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/in.h>

char *
inet_ntoa(in)
	struct in_addr in;
{
	static char b[18];
	register char *p;

	p = (char *)&in;
#define	UC(b)	(((int)b)&0xff)
	sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
	return (b);
}
 base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) {
		if (isdigit(c)) {
			val = (val * base) + (c - '0');
			cp++;
			continue;
		}
		if (base == 16 && isxdigit(c)) {
			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
			cp++;
			continueunix/lib/listen.c                                                                                      444     322     145         1003  3621344600   7307                                                                                                                                                                                                                                                                                                                                                                      
/*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding July 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>

listen (s, backlog)
{

	if (ioctl (s, SIOCLISN, backlog) < 0)
		return (-1);
	else	return (0);
}
(in)
	struct in_addr in;
{
	static char b[18];
	register char *p;

	p = (char *)&in;
#define	UC(b)	(((int)b)&0xff)
	sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
	return (b);
}
 base = 10;
	if (*cp == '0')
		base = 8, cp++;
	if (*cp == 'x' || *cp == 'X')
		base = 16, cp++;
	while (c = *cp) {
		if (isdigit(c)) {
			val = (val * base) + (c - '0');
			cp++;
			continue;
		}
		if (base == 16 && isxdigit(c)) {
			val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
			cp++;
			continueunix/lib/net_error.c                                                                                   444     322     145         1700  3621344601  10015                                                                                                                                                                                                                                                                                                                                                                       (   (  /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * Get a pointer to the message for a given error code.
 */

#include <stdio.h>
#include <CMC/errno.h>

char *
net_error (errnum)
int errnum;
{
extern int	sys_nerr;	/* num std err messages */
extern char	*sys_errlist[];	/* text for std messages */
extern char	*nsys_errlist[];/* text for network messages */
extern int	nsys_nerr;	/* num network messages */
static char	unknown[48];


	if (EWOULDBLOCK <= errnum && errnum < nsys_nerr+EWOULDBLOCK)
		return (nsys_errlist[errnum-EWOULDBLOCK]);
	else
	if (errnum > 0 && errnum < sys_nerr)
		return (sys_errlist[errnum]);
	else {
		sprintf ( unknown, "Unknown error code %d", errnum );
		return (unknown);
	}
}
< 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
			cp++;
			continueunix/lib/opendir.c                                                                                     444     322     145          377  3621344601   7447                                                                                                                                                                                                                                                                                                                                                                      #ifndef lint
static char sccsid[] = "@(#)opendir.c	4.5 (Berkeley) 7/1/83";
#endif

#include <CMC/types.h>
#include <CMC/dir.h>

/*
 * open a directory.
 */
opendir(name)
	char *name;
{
	if ( name && (*name == 0) )
		name = ".";
	return (open(name, 0));
}
 of Communication Machinery Corporation.
 */

/*
 * Get a pointer to the message for a given error code.
 */

#include <stdio.h>
#include <CMC/errno.h>

char *
net_error (errnum)
int errnum;
{
extern int	sys_nerr;	/* num std err messages */
extern char	*sysunix/lib/perror.c                                                                                      444     322     145         3157  3621344601   7337                                                                                                                                                                                                                                                                                                                                                                      
#include <stdio.h>
#include <CMC/errno.h>

char *nsys_errlist[] = {	/* network error messages */
	"Operation would block",
	"Operation now in progress",
	"Operation already in progress",
	"Socket operation on non-socket",
	"Destination address required",
	"Message too long",
	"Protocol wrong type for socket",
	"Protocol not available",
	"Protocol not supported",
	"Socket type not supported",
	"Operation not supported on socket",
	"Protocol family not supported",
	"Address family not supported by protocol family",
	"Address already in use",
	"Can't assign requested address",
	"Network is down",
	"Network is unreachable",
	"Network dropped connection on reset",
	"Software caused connection abort",
	"Connection reset by peer",
	"No buffer space available",
	"Socket is already connected",
	"Socket is not connected",
	"Can't send after socket shutdown",
	"Too many references: can't splice",
	"Connection timed out",
	"Connection refused",
	"Too many levels of symbolic links",
	"File name too long",
	"Host is down",
	"Host is unreachable",
};
int nsys_nerr = (sizeof(nsys_errlist)/sizeof(nsys_errlist[0]));

void
perror (s)
char *s;
{
extern int	errno;
extern int	sys_nerr;	/* num std err messages */
extern char	*sys_errlist[];	/* text for std messages */
char		*colon = ": ";


	if (s == 0)
		s = "";
	if (*s == 0)
		colon = "";
	if (EWOULDBLOCK <= errno && errno < nsys_nerr+EWOULDBLOCK)
		fprintf (stderr, "%s%s%s\n", 
			s, colon, nsys_errlist[errno-EWOULDBLOCK]);
	else
	if (errno > 0 && errno < sys_nerr)
		fprintf (stderr, "%s%s%s\n", s, colon, sys_errlist[errno]);
	else
		fprintf (stderr, "%s%sError %d\n", s, colon, errno);
}
 parts;
	switch (n) {

	case 1:				/* a -- 32 bits */
		val = parts[0];
		break;

	case 2:				/* a.b -- 8.24 bits */
		val = (parts[0] << 24) | (parts[1] & 0xffffff);
		break;

	case 3:				/* a.b.c -- 8.8.16 bits */
		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |
			(parts[2] & 0xffff);
		break;

	case 4:				/* a.b.c.d -- 8.8.8.8 bits */
		val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) |unix/lib/rcmd.c                                                                                        444     322     145         7261  3621344602   6754                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)rcmd.c CMC	4.8 3/19/83";
#endif

#include <stdio.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>

#include <CMC/in.h>

#include <CMC/netdb.h>
#include <CMC/errno.h>

extern	errno;
char	*strchr(), *sprintf();

rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
	char **ahost;
	int rport;
	char *locuser, *remuser, *cmd;
	int *fd2p;
{
	int s, timo = 1;
	struct sockaddr_in sin, sin2, from;
	char c;
	int lport = IPPORT_RESERVED - 1;
	struct hostent *hp;

	hp = gethostbyname(*ahost);
	if (hp == 0) {
		fprintf(stderr, "%s: unknown host\n", *ahost);
		return (-1);
	}
	*ahost = hp->h_name;
retry:
	s = rresvport(&lport);
	if (s < 0)
		return (-1);
	sin.sin_family = hp->h_addrtype;
	memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
	sin.sin_port = rport;
	if (connect(s, (caddr_t)&sin, sizeof (sin)) < 0) {
		if (errno == EADDRINUSE) {
			close(s);
			lport--;
			goto retry;
		}
		if (errno == ECONNREFUSED && timo <= 16) {
			(void) close(s);
			sleep(timo);
			timo *= 2;
			goto retry;
		}
		perror(hp->h_name);
		return (-1);
	}
	lport--;
	if (fd2p == 0) {
		write(s, "", 1);
		lport = 0;
	} else {
		char num[8];
		int s2 = rresvport(&lport), s3;

		if (s2 < 0) {
			(void) close(s);
			return (-1);
		}
		listen(s2, 1);
		(void) sprintf(num, "%d", lport);
		if (write(s, num, strlen(num)+1) != strlen(num)+1) {
			perror("write: setting up stderr");
			(void) close(s2);
			goto bad;
		}
		{ int len = sizeof (from);
		  s3 = accept(s2, &from, &len);
		  close(s2);
		  if (s3 < 0) {
			perror("accept");
			lport = 0;
			goto bad;
		  }
		}
		*fd2p = s3;
		from.sin_port = ntohs((u_short)from.sin_port);
		if (from.sin_family != AF_INET ||
		    from.sin_port >= IPPORT_RESERVED) {
			fprintf(stderr,
			    "socket: protocol failure in circuit setup.\n");
			goto bad2;
		}
	}
	(void) write(s, locuser, strlen(locuser)+1);
	(void) write(s, remuser, strlen(remuser)+1);
	(void) write(s, cmd, strlen(cmd)+1);
	if (read(s, &c, 1) != 1) {
		perror(*ahost);
		goto bad2;
	}
	if (c != 0) {
		while (read(s, &c, 1) == 1) {
			(void) write(2, &c, 1);
			if (c == '\n')
				break;
		}
		goto bad2;
	}
	return (s);
bad2:
	if (lport)
		(void) close(*fd2p);
bad:
	(void) close(s);
	return (-1);
}

rresvport(alport)
	int *alport;
{
	struct sockaddr_in sin;
	int s;

	sin.sin_family = AF_INET;
	sin.sin_addr.s_addr = 0;
	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s < 0)
		return (-1);
	for (;;) {
		sin.sin_port = htons((u_short)*alport);
		if (bind(s, (caddr_t)&sin, sizeof (sin)) >= 0)
			return (s);
		if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
			perror("socket");
			return (-1);
		}
		(*alport)--;
		if (*alport == IPPORT_RESERVED/2) {
			fprintf(stderr, "socket: All ports in use\n");
			return (-1);
		}
	}
}

ruserok(rhost, superuser, ruser, luser)
	char *rhost;
	int superuser;
	char *ruser, *luser;
{
	FILE *hostf;
	char ahost[32];
	int first = 1;

	hostf = superuser ? (FILE *)0 : fopen("/etc/hosts.equiv", "r");
again:
	if (hostf) {
		while (fgets(ahost, sizeof (ahost), hostf)) {
			char *user;
			if (strchr(ahost, '\n'))
				*strchr(ahost, '\n') = 0;
			user = strchr(ahost, ' ');
			if (user)
				*user++ = 0;
			if (!strcmp(rhost, ahost) &&
			    !strcmp(ruser, user ? user : luser)) {
				(void) fclose(hostf);
				return (0);
			}
		}
		(void) fclose(hostf);
	}
	if (first == 1) {
		first = 0;
		hostf = fopen(".rhosts", "r");
		goto again;
	}
	return (-1);
}
0x10	/* A late collision occurred on transmission. */
#define EX_CAR	0x08	/* Carrier was lost during transmission. */
#define EX_RTRY	0x04	/* Retry failure. */
#define EX_MERR	0x02	/* A memory error occured on transmit. */
#define EX_CERR	0x01	/* A collision error was reported. */

#if !defined(vax)
/*
 * Macros for number representaunix/lib/readdir.c                                                                                     444     322     145         1203  3621344602   7427                                                                                                                                                                                                                                                                                                                                                                      /*
 * Modified to read System 5 (and earlier) style directories.
 *			Deb Brown, CMC		August 20, 1984
 */

#ifndef lint
static char sccsid[] = "@(#)readdir.c	4.5 (Berkeley) 7/1/83";
#endif

#include <CMC/types.h>
#include <CMC/dir.h>
#include <memory.h>

/*
 * get next entry in a directory.
 */
struct direct *
readdir(dirid)
	int dirid;
{
	static struct direct dp;
	struct dir_s5 d5;

	for (;;)
	{
		if (read (dirid, &d5, sizeof (d5)) != sizeof (d5))
			return (struct direct *) NULL;
		if (d5.d5_ino != 0)
		{ (   (  
			dp.d_ino = d5.d5_ino;
			memcpy (dp.d_name, d5.d5_name, MAXNAMLEN);
			dp.d_name [MAXNAMLEN] = NULL;
			return (&dp);
		}
	}
}
 sccsid[] = "@(#)readdir.c	4.5 (Berkeley) 7/1/83";
#endif

#include <CMC/types.h>
#include <CMC/dir.h>
#include <memory.h>

/*
 * get next entry in a directory.
 */
struct direct *
readdir(dirid)
	int dirid;
{
	static struct direct dp;
	struct dir_s5 d5;

	for (;;)
	{
		if (read (dirid, &d5, sizeof (d5)) != sizeof (d5))
			return (struct direct *) NULL;
		if (d5.d5_ino != 0)
		{unix/lib/recv.c                                                                                        444     322     145         1305  3621344603   6760                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding November 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>

recv (s, mesg, len, flags)
char *mesg;
{
	userparm pblock;
	register userparm *pb = &pblock;
	register count;

	pb->p_where = mesg;
	pb->p_len = len;
	pb->p_len2 = flags;		/* non-standard use of len2 */

	if ((count = ioctl (s, SIOCRECV, pb)) < 0)
		return (-1);
	else	return (count);
}

timo = 1;
	struct sockaddr_in sin, sin2, from;
	char c;
	int lport = IPPORT_RESERVED - 1;
	struct hostent *hp;

	hp = gethostbyname(*ahost);
	if (hp == 0) {
		fprintf(stderr, "%s: unknown host\n", *ahost);
		return (-1);
	}
	*ahost = hp->h_name;
retry:
	s = rresvport(&lport);
	if (s < 0)
		return (-1);
	sin.sin_faunix/lib/recvfrom.c                                                                                    444     322     145         1501  3621344603   7642                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding June 1985 by Doug Miller
 */

# include <CMC/types.h>
# include <CMC/longnames.h>
# include <CMC/user_socket.h>

recvfrom (s, mesg, len, flags, from, fromlen)
char *mesg;
char *from;
int *fromlen;
{
	userparm pblock;
	register userparm *pb = &pblock;
	register count;

	pb->p_where = mesg;
	pb->p_len = len;
	pb->p_len2 = flags;		/* non-standard use of len2 */
	pb->p_where3 = from;
	pb->p_len3 = (int) fromlen;

	if ((count = ioctl (s, SIOCRECVFROM, pb)) < 0)
		return (-1);
	else	return (count);
}

tbyname(*ahost);
	if (hp == 0) {
		fprintf(stderr, "%s: unknown host\n", *ahost);
		return (-1);
	}
	*ahost = hp->h_name;
retry:
	s = rresvport(&lport);
	if (s < 0)
		return (-1);
	sin.sin_faunix/lib/ruserpass.c                                                                                   444     322     145        36345  3621344605  10106                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */


static char sccsid[] = "@(#)ruserpass.c 5.0 (CMC) 9/20/84";

#include <CMC/types.h>
#include <stdio.h>
#include <utmp.h>
#include <ctype.h>
#include <sys/stat.h>
#include <CMC/errno.h>

char	*renvlook(), *malloc(), *strchr(), *getenv(), *getpass(), *getlogin();
struct	utmp *getutmp();
static	FILE *cfile;

ruserpass(host, aname, apass)
	char *host, **aname, **apass;
{

	renv(host, aname, apass);
	if (*aname == 0 || *apass == 0)
		rnetrc(host, aname, apass);
	if (*aname == 0) {
		char *myname = getlogin();
		*aname = malloc(16);
		printf("Name (%s:%s): ", host, myname);
		fflush(stdout);
		if (read(2, *aname, 16) <= 0)
			exit(1);
		if ((*aname)[0] == '\n')
			*aname = myname;
		else
			if (strchr(*aname, '\n'))
				*strchr(*aname, '\n') = 0;
	}
	if (*aname && *apass == 0) {
		printf("Password (%s:%s): ", host, *aname);
		fflush(stdout);
		*apass = getpass("");
	}
}

static
renv(host, aname, apass)
	char *host, **aname, **apass;
{
	register char *cp;
	char *stemp, fgetlogin, *comma;

	cp = renvlook(host);
	if (cp == NULL)
		return;
	if (!isalpha(cp[0]))
		return;
	comma = strchr(cp, ',');
	if (comma == 0)
		return;
	if (*aname == 0) {
		*aname = malloc(comma - cp + 1);
		strncpy(*aname, cp, comma - cp);
	} else
		if (strncmp(*aname, cp, comma - cp))
			return;
	comma++;
	cp = malloc(strlen(comma)+1);
	strcpy(cp, comma);
	*apass = malloc(16);
	mkpwclear(cp, host[0], *apass);
}

static
char *
renvlook(host)
	char *host;
{
	register char *cp, **env;
	extern char **environ;

	env = environ;
	for (env = environ; *env != NULL; env++)
		if (!strncmp(*env, "MACH", 4)) {
			cp = strchr(*env, '=');
			if (cp == 0)
				continue;
			if (strncmp(*env+4, host, cp-(*env+4)))
				continue;
			return (cp+1);
		}
	return (NULL);
}

#define	DEFAULT	1
#define	LOGIN	2
#define	PASSWD	3
#define	NOTIFY	4
#define	WRITE	5
#define	YES	6
#define	NO	7
#define	COMMAND	8
#define	FORCE	9
#define	ID	10
#define	MACHINE	11

static char tokval[100];

static struct toktab {
	char *tokstr;
	int tval;
} toktab[]= {
	"default",	DEFAULT,
	"login",	LOGIN,
	"password",	PASSWD,
	"notify",	NOTIFY,
	"write",	WRITE,
	"yes",		YES,
	"y",		YES,
	"no",		NO,
	"n",		NO,
	"command",	COMMAND,
	"force",	FORCE,
	"machine",	MACHINE,
	0,		0
};

static
rnetrc(host, aname, apass)
	char *host, **aname, **apass;
{
	char *hdir, buf[BUFSIZ];
	int t;
	struct stat stb;
	extern int errno;

	hdir = getenv("HOME");
	if (hdir == NULL)
		hdir = ".";
	sprintf(buf, "%s/.netrc", hdir);
	cfile = fopen(buf, "r");
	if (cfile == NULL) {
		if (errno != ENOENT)
			perror(buf);
		return;
	}
next:
	while ((t = token())) switch(t) {

	case DEFAULT:
		(void) token();
		continue;

	case MACHINE:
		if (token() != ID || strcmp(host, tokval))
			continue;
		while ((t = token()) && t != MACHINE) switch(t) {

		case LOGIN:
			if (token())
				if (*aname == 0) { 
					*aname = malloc(strlen(tokval) + 1);
					strcpy(*aname, tokval);
				} else {
					if (strcmp(*aname, tokval))
						goto next;
				}
			break;
		case PASSWD:
			if (fstat(fileno(cfile), &stb) >= 0
			    && (stb.st_mode & 077) != 0) {
	fprintf(stderr, "Error - .netrc file not correct mode.\n");
	fprintf(stderr, "Remove password or correct mode.\n");
				exit(1);
			}
			if (token() && *apass == 0) {
				*apass = malloc(strlen(tokval) + 1);
				strcpy(*apass, tokval);
			}
			break;
		case COMMAND:
		case NOTIFY:
		case WRITE:
		case FORCE:
			(void) token();
			break;
		default:
	fprintf(stderr, "Unknown .netrc option %s\n", tokval);
			break;
		}
		goto done;
	}
done:
	fclose(cfile);
}

static
token()
{
	char *cp;
	int c;
	struct toktab *t;

	if (feof(cfile))
		return (0);
	while ((c = getc(cfile)) != EOF &&
	    (c == '\n' || c == '\t' || c == ' ' || c == ','))
		continue;
	if (c == EOF)
		return (0);
	cp = tokval;
	if (c == '"') {
		while ((c = getc(cfile)) != EOF && c != '"') {
			if (c == '\\')
				c = getc(cfile);
			*cp++ = c;
		}
	} else {
		*cp++ = c;
		while ((c = getc(cfile)) != EOF
		    && c != '\n' && c != '\t' && c != ' ' && c != ',') {
			if (c == '\\')
				c = getc(cfile);
			*cp++ = c;
		}
	}
	*cp = 0;
	if (tokval[0] == 0)
		return (0);
	for (t = toktab; t->tokstr; t++)
		if (!strcmp(t->tokstr, tokval))
			return (t->tval);
	return (ID);
}
/* rest is nbs.c stolen from berknet */

char *deblknot(), *deblkclr();
char *nbs8decrypt(), *nbs8encrypt();
static char	E[48];

/*
 * The E bit-selection table.
 */
static char	e[] = {
	32, 1, 2, 3, 4, 5,
	 4, 5, 6, 7, 8, 9,
	 8, 9,10,11,12,13,
	12,13,14,15,16,17,
	16,17,18,19,20,21,
	20,21,22,23,24,25,
	24,25,26,27,28,29,
	28,29,30,31,32, 1,
};
static
char *nbsencrypt(str,key,result)
  char *result;
  char *str, *key; {
	static char buf[20],oldbuf[20];
	register int j;
	result[0] = 0;
	strcpy(oldbuf,key);
	while(*str){
		for(j=0;j<10;j++)buf[j] = 0;
		for(j=0;j<8 && *str;j++)buf[j] = *str++;
		strcat(result,nbs8encrypt(buf,oldbuf));
		strcat(result,"$");
		strcpy(oldbuf,buf);
		}
	return(result);
	}
static
char *nbsdecrypt(cpt,key,result)
  char *result;
  char *cpt,*key; {
	char *s;
	char c,oldbuf[20];
	result[0] = 0;
	strcpy(oldbuf,key);
	while(*cpt){
		for(s = cpt;*s && *s != '$';s++);
		c = *s;
		*s = 0;
		strcpy(oldbuf,nbs8decrypt(cpt,oldbuf));
		strcat(result,oldbuf);
		if(c == 0)break;
		cpt = s + 1;
		}
	return(result);
	}

static
char *nbs8encrypt(str,key)
char *str, *key; {
	static char keyblk[100], blk[100];
	register int i;

	enblkclr(keyblk,key);
	nbssetkey(keyblk);

	for(i=0;i<48;i++) E[i] = e[i];
	enblkclr(blk,str);
	blkencrypt(blk,0);			/* forward dir */

	return(deblknot(blk));
}

static
char *nbs8decrypt(crp,key)
char *crp, *key; {
	static char keyblk[100], blk[100];
	register int i;

	enblkclr(keyblk,key);
	nbssetkey(keyblk);

	for(i=0;i<48;i++) E[i] = e[i];
	enblknot(blk,crp);
	blkencrypt(blk,1);			/* backward dir */

	return(deblkclr(blk));
}

static
enblkclr(blk,str)		/* ignores top (   (   bit of chars in string str */
char *blk,*str; {
	register int i,j;
	char c;
	for(i=0;i<70;i++)blk[i] = 0;
	for(i=0; (c= *str) && i<64; str++){
		for(j=0; j<7; j++, i++)
			blk[i] = (c>>(6-j)) & 01;
		i++;
		}
	}

static
char *deblkclr(blk)
char *blk; {
	register int i,j;
	char c;
	static char iobuf[30];
	for(i=0; i<10; i++){
		c = 0;
		for(j=0; j<7; j++){
			c <<= 1;
			c |= blk[8*i+j];
			}
		iobuf[i] = c;
	}
	iobuf[i] = 0;
	return(iobuf);
	}

static
enblknot(blk,crp)
char *blk;
char *crp; {
	register int i,j;
	char c;
	for(i=0;i<70;i++)blk[i] = 0;
	for(i=0; (c= *crp) && i<64; crp++){
		if(c>'Z') c -= 6;
		if(c>'9') c -= 7;
		c -= '.';
		for(j=0; j<6; j++, i++)
			blk[i] = (c>>(5-j)) & 01;
		}
	}

static
char *deblknot(blk)
char *blk; {
	register int i,j;
	char c;
	static char iobuf[30];
	for(i=0; i<11; i++){
		c = 0;
		for(j=0; j<6; j++){
			c <<= 1;
			c |= blk[6*i+j];
			}
		c += '.';
		if(c > '9')c += 7;
		if(c > 'Z')c += 6;
		iobuf[i] = c;
	}
	iobuf[i] = 0;
	return(iobuf);
}

/*
 * This program implements the
 * Proposed Federal Information Processing
 *  Data Encryption Standard.
 * See Federal Register, March 17, 1975 (40FR12134)
 */

/*
 * Initial permutation,
 */
static	char	IP[] = {
	58,50,42,34,26,18,10, 2,
	60,52,44,36,28,20,12, 4,
	62,54,46,38,30,22,14, 6,
	64,56,48,40,32,24,16, 8,
	57,49,41,33,25,17, 9, 1,
	59,51,43,35,27,19,11, 3,
	61,53,45,37,29,21,13, 5,
	63,55,47,39,31,23,15, 7,
};

/*
 * Final permutation, FP = IP^(-1)
 */
static	char	FP[] = {
	40, 8,48,16,56,24,64,32,
	39, 7,47,15,55,23,63,31,
	38, 6,46,14,54,22,62,30,
	37, 5,45,13,53,21,61,29,
	36, 4,44,12,52,20,60,28,
	35, 3,43,11,51,19,59,27,
	34, 2,42,10,50,18,58,26,
	33, 1,41, 9,49,17,57,25,
};

/*
 * Permuted-choice 1 from the key bits
 * to yield C and D.
 * Note that bits 8,16... are left out:
 * They are intended for a parity check.
 */
static	char	PC1_C[] = {
	57,49,41,33,25,17, 9,
	 1,58,50,42,34,26,18,
	10, 2,59,51,43,35,27,
	19,11, 3,60,52,44,36,
};

static	char	PC1_D[] = {
	63,55,47,39,31,23,15,
	 7,62,54,46,38,30,22,
	14, 6,61,53,45,37,29,
	21,13, 5,28,20,12, 4,
};

/*
 * Sequence of shifts used for the key schedule.
*/
static	char	shifts[] = {
	1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,
};

/*
 * Permuted-choice 2, to pick out the bits from
 * the CD array that generate the key schedule.
 */
static	char	PC2_C[] = {
	14,17,11,24, 1, 5,
	 3,28,15, 6,21,10,
	23,19,12, 4,26, 8,
	16, 7,27,20,13, 2,
};

static	char	PC2_D[] = {
	41,52,31,37,47,55,
	30,40,51,45,33,48,
	44,49,39,56,34,53,
	46,42,50,36,29,32,
};

/*
 * The C and D arrays used to calculate the key schedule.
 */

static	char	C[28];
static	char	D[28];
/*
 * The key schedule.
 * Generated from the key.
 */
static	char	KS[16][48];

/*
 * Set up the key schedule from the key.
 */

static
nbssetkey(key)
char *key;
{
	register i, j, k;
	int t;

	/*
	 * First, generate C and D by permuting
	 * the key.  The low order bit of each
	 * 8-bit char is not used, so C and D are only 28
	 * bits apiece.
	 */
	for (i=0; i<28; i++) {
		C[i] = key[PC1_C[i]-1];
		D[i] = key[PC1_D[i]-1];
	}
	/*
	 * To generate Ki, rotate C and D according
	 * to schedule and pick up a permutation
	 * using PC2.
	 */
	for (i=0; i<16; i++) {
		/*
		 * rotate.
		 */
		for (k=0; k<shifts[i]; k++) {
			t = C[0];
			for (j=0; j<28-1; j++)
				C[j] = C[j+1];
			C[27] = t;
			t = D[0];
			for (j=0; j<28-1; j++)
				D[j] = D[j+1];
			D[27] = t;
		}
		/*
		 * get Ki. Note C and D are concatenated.
		 */
		for (j=0; j<24; j++) {
			KS[i][j] = C[PC2_C[j]-1];
			KS[i][j+24] = D[PC2_D[j]-28-1];
		}
	}
}


/*
 * The 8 selection functions.
 * For some reason, they give a 0-origin
 * index, unlike everything else.
 */
static	char	S[8][64] = {
	14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7,
	 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8,
	 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0,
	15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13,

	15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10,
	 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5,
	 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15,
	13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9,

	10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8,
	13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1,
	13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7,
	 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12,

	 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15,
	13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9,
	10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4,
	 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14,

	 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9,
	14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6,
	 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14,
	11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3,

	12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11,
	10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8,
	 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6,
	 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13,

	 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1,
	13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6,
	 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2,
	 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12,

	13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7,
	 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2,
	 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8,
	 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11,
};

/*
 * P is a permutation on the selected combination
 * of the current L and key.
 */
static	char	P[] = {
	16, 7,20,21,
	29,12,28,17,
	 1,15,23,26,
	 5,18,31,10,
	 2, 8,24,14,
	32,27, 3, 9,
	19,13,30, 6,
	22,11, 4,25,
};

/*
 * The current block, divided into 2 halves.
 */
static	char	L[32], R[32];
static	char	tempL[32];
static	char	f[32];

/*
 * The combination of the key and the input, before selection.
 */
static	char	preS[48];

/*
 * The payoff: encrypt a block.
 */

static
blkencrypt(block, edflag)
char *block;
{
	int i, ii;
	register t, j, k;

	/*
	 * First, permute the bits in the input
	 */
	for (j=0; j<64; j++)
		L[j] = block[IP[j]-1];
	/*
	 * Perform an encryption operation 16 times.
	 */
	for (ii=0; ii<16; ii++) {
		/*
		 * Set direction
		 */
		if (edflag)
			i = 15-ii;
		else
			i = ii;
		/*
		 * Save the R array,
		 * which will be the new L.
		 */
		for (j=0; j<32; j++)
			tempL[j] = R[j];
		/*
		 * Expand R to 48 bits using the E selector;
		 * exclusive-or with the current key bits.
		 */
		for (j=0; j<48; j++)
			preS[j] = R[E[j]-1] ^ KS[i][j];
		/*
		 * The pre-select bits are now considered
		 * in 8 groups of 6 bits each.
		 * The 8 selection functions map these
		 * 6-bit quantities into 4-bit quantities
		 * and the results permuted
		 * to make an f(R, K).
		 * The indexing into the selection functions
		 * is peculiar; it could be simplified by
		 * rewriting the tables.
		 */
		for (j=0; j<8; j++) {
			t = 6*j;
			k = S[j][(preS[t+0]<<5)+
				(preS[t+1]<<3)+
				(preS[t+2]<<2)+
				(preS[t+3]<<1)+
				(preS[t+4]<<0)+
				(preS[t+5]<<4)];
			t = 4*j;
			f[t+0] = (k>>3)&01;
			f[t+1] = (k>>2)&01;
			f[t+2] = (k>>1)&01;
			f[t+3] = (k>>0)&01;
		}
		/*
		 * The new R is L ^ f(R, K).
		 * The f here has to be permuted first, though.
		 */
		for (j=0; j<32; j++)
			R[j] = L[j] ^ f[P[j]-1];
		/*
		 * Finally, the new L (the original R)
		 * is copied back.
		 */
		for (j=0; j<32; j++)
			L[j] = tempL[j];
	}
	/*
	 * The output L and R are reversed.
	 */
	for (j=0; j<32; j++) {
		t = L[j];
		L[j] = R[j];
		R[j] = t;
	}
	/*
	 * The final output
	 * gets the inverse permutation of the very original.
	 */
	for (j=0; j<64; j++)
		block[j] = L[FP[j]-1];
}
/*
	getutmp()
	return a pointer to the system utmp structure associated with
	terminal sttyname, e.g. "/dev/tty3"
	Is version independent-- will work on v6 systems
	return NULL if error
*/
static
struct utmp *getutmp(sttyname)
char *sttyname;
{
	static struct utmp utmpstr;
	FILE *fdutmp;

	if(sttyname == NULL || sttyname[0] == 0)return(NULL);

	fdutmp = fopen("/etc/utmp","r");
	if(fdutmp == NULL)return(NULL);

	while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr)
		if(strcmp(utmpstr.ut_line,sttyname+5) == 0){
			fclose(fdutmp);
			return(&utmpstr);
		}
	fclose(fdutmp);
	return(NULL);
}

static
sreverse(sto, sfrom)
	register char *sto, *sfrom;
{
	register int i;

	i = strlen(sfrom);
	while (i >= 0)
		*sto++ = sfrom[i--];
}

static
char *mkenvkey(mch)
	char mch;
{
	static char skey[40];
	register struct utmp *putmp;
	char stemp[40], stemp1[40], sttyname[30];
	register char *sk,*p;

	if (isatty(2))
		strcpy(sttyname,ttyname(2));
	else if (isatty(0))
		strcpy(sttyname,ttyname(0));
	else if (isatty(1))
		strcpy(sttyname,ttyname(1));
	else
		return (NULL);
	putmp = getutmp(sttyname);
	if (putmp == NULL)
		return (NULL);
	sk = skey;
	p = putmp->ut_line;
	while (*p)
		*sk++ = *p++;
	*sk++ = mch;
	sprintf(stemp, "%ld", putmp->ut_time);
	sreverse(stemp1, stemp);
	p = stemp1;
	while (*p)
		*sk++ = *p++;
	*sk = 0;
	return (skey);
}

mkpwunclear(spasswd,mch,sencpasswd)
	char mch, *spasswd, *sencpasswd;
{
	register char *skey;

	if (spasswd[0] == 0) {
		sencpasswd[0] = 0;
		return;
	}
	skey = mkenvkey(mch);
	if (skey == NULL) {
		fprintf(stderr, "Can't make key\n");
		exit(1);
	}
	nbsencrypt(spasswd, skey, sencpasswd);
}

mkpwclear(sencpasswd,mch,spasswd)
	char mch, *spasswd, *sencpasswd;
{
	register char *skey;

	if (sencpasswd[0] == 0) {
		spasswd[0] = 0;
		return;
	}
	skey = mkenvkey(mch);
	if (skey == NULL) {
		fprintf(stderr, "Can't make key\n");
		exit(1);
	}
	nbsdecrypt(sencpasswd, skey, spasswd);
}
240484080C1300280C1424058
S210F08FE448406000003C2601E280E2817C
S210F08FF002807FFFFFFF02817FFFFFFF83
S210F08FFC0C81000100006C00FFE880C152
S210F0900802800000FFFF2F002F034EB97F
S210F0901400F0902C508FB4806C0290831B
S210F09020908244804CDF000C4E5E4E75D3
S210F0902C48E73000242F000C262F00102unix/lib/send.c                                                                                        444     322     145         1305  3621344606   6755                                                                                                                                                                                                                                                                                                                                                                       (   (  /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding November 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>

send (s, mesg, len, flags)
char *mesg;
{
	userparm pblock;
	register userparm *pb = &pblock;
	register count;

	pb->p_where = mesg;
	pb->p_len = len;
	pb->p_len2 = flags;		/* non-standard use of len2 */

	if ((count = ioctl (s, SIOCSEND, pb)) < 0)
		return (-1);
	else	return (count);
}

static
char *deblknot(blk)
char *blk; {
	register int i,j;
	char c;
	static char iobuf[30];
	for(i=0; i<11; i++){
		c = 0;
		for(j=0; j<6; j++){
			c <<= 1;
			c |= blk[6*i+j];
			}
		c += '.';
		if(c > '9')c += 7;
		if(c > 'Z')c += 6;
		iobuf[i] = c;
	}
	iobuf[i] = 0;
	return(iobuf);
}

/*
 * This program implemeunix/lib/sendto.c                                                                                      444     322     145         1424  3621344606   7322                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 *
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	HISTORY:
 *		Initial coding June 1985 by Doug Miller
 */

# include <CMC/types.h>
# include <CMC/longnames.h>
# include <CMC/user_socket.h>

sendto (s, mesg, len, flags, to, tolen)
char *mesg, *to;
{
	userparm pblock;
	register userparm *pb = &pblock;
	register count;

	pb->p_where = mesg;
	pb->p_len = len;
	pb->p_len2 = flags;		/* non-standard use of len2 */
	pb->p_where3 = to;
	pb->p_len3 = tolen;

	if ((count = ioctl (s, SIOCSENDTO, pb)) < 0)
		return (-1);
	else	return (count);
}
r iobuf[30];
	for(i=0; i<11; i++){
		c = 0;
		for(j=0; j<6; j++){
			c <<= 1;
			c |= blk[6*i+j];
			}
		c += '.';
		if(c > '9')c += 7;
		if(c > 'Z')c += 6;
		iobuf[i] = c;
	}
	iobuf[i] = 0;
	return(iobuf);
}

/*
 * This program implemeunix/lib/shutdown.c                                                                                    444     322     145         1012  3621344607   7673                                                                                                                                                                                                                                                                                                                                                                      
/*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	History:
 *
 *	Initial coding October 2, 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>

shutdown (s, how)
{

	if ( ioctl (s, SIOCSHUT, how) < 0 )
		return (-1);
	else	return (0);
}
ster userparm *pb = &pblock;
	register count;

	pb->p_where = mesg;
	pb->p_len = len;
	pb->p_len2 = flags;		/* non-standard use of len2 */
	pb->p_where3 = to;
	pb->p_len3 = tolen;

	if ((count = ioctl (s, SIOCSENDTO, pb)) < 0)
		return (-1);
	else	return (count);
}
r iobuf[30];
	for(i=0; i<11; i++){
		c = 0;
		for(j=0; j<6; j++){
			c <<= 1;
			c |= blk[6*i+j];
			}
		c += '.';
		if(c > '9')c += 7;
		if(c > 'Z')c += 6;
		iobuf[i] = c;
	}
	iobuf[i] = 0;
	return(iobuf);
}

/*
 * This program implemeunix/lib/socket.c                                                                                      444     322     145         3154  3621344607   7321                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	This file implements the semantics of the 4.2BSD 
 *	"socket" system call.  It is (temporally) the first
 *	routine which must be invoked.
 */

/*	HISTORY:
 *		Initial coding July 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/user_socket.h>
# include <CMC/errno.h>

# define SOCKBASE "/dev/socket/s%d"

static int socketerrs[] = {
	EAFNOSUPPORT,
	ESOCKTNOSUPPORT,
	EPROTONOSUPPORT,
	EMFILE,
	ENOBUFS,
	};

static int errct = sizeof(socketerrs)/sizeof(socketerrs[0]);

socket (af, type, proto)
{
	register sd;		/* the "socket" */

	sd = opensock (af, type, proto);
	if (sd < 0)
		sd = -1;
	return (sd);
}

static
opensock (af, type, proto)
{
	char sockname[32];
	register short i;
	register int fd;
	register int error;
	extern errno;

	for (i=1; i <= NSOCKETS; i++) {
		sprintf (sockname, SOCKBASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd < 0)
			continue;
		if (ioctl (fd, SIOCRESV, &af) >= 0)
			return (fd);
		else	{
			error = errno;
			close (fd);
			if (one_of (error, socketerrs, errct) >= 0) {
				errno = error;
				return (-1);
			}
			else	break;		/* return ENOBUFS */
		}
		
	}

	errno = ENOBUFS;
	return (-1);
}

static
one_of (guess, set, setsize)
register int *set;
{
	register short i;

	for (i=0; i<setsize; i++) {
		if ( *set++ == guess )
			return (i);
	}

	return (-1);
}

	34, 2,42,10,50,18,58,26,
	33, 1,41, 9,49,17,57,25,
};

/*
 * Permuted-choice 1 from the key bits
 * to yield C and D.
 * Note that bits 8,16... are left out:
 * They are intended for a parity check.
 */
static	char	PC1_C[] = {
	57,49,41,33,25,17, 9,
	 1,58,50,42,34,26,18,
	10, 2,59,51,43,35,27,
	19,11, 3,60,52,44,36,
};

static	char	PC1_D[] = {
	63,55,47,39,31,23,15,
	 7,62,54,46,38,30,22,
	14, 6,61unix/lib/sockopt.c                                                                                     444     322     145         2137  3621344610   7505                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	History:
 *
 *	Initial coding October 2, 1984 by John Mullen
 */

# include <CMC/types.h>
# include <CMC/longnames.h>
# include <CMC/user_socket.h>

setsockopt (s, lev, nm, val, len)
char *val;
{
	userparm parm;
	register userparm *pb = &parm;

	pb->p_where = val;
	pb->p_len = len;
	pb->p_where2 = (char *) lev;	/* non-standard use of where2 */
	pb->p_len2 = nm;		/* ditto for len2 */

	if ( ioctl (s, SIOCSOPT, pb) < 0 )
		return (-1);
	else	return (0);
}

getsockopt (s, lev, nm, val, len)
char *val;
int *len;
{
	userparm parm;
	register userparm *pb = &parm;

	pb->p_where = val;
	pb->p_len = (int) len;		/* non-standard use len */
	pb->p_where2 = (char *) lev;	/* non-standard use of where2 */
	pb->p_len2 = nm;		/* ditto for len2 */

	if ( ioctl (s, SIOCGOPT, pb) < 0 )
		return (-1);
	else	return (0);
}
ASE, i);
		fd = open (sockname, 2);	/* try to open a socket */
		if (fd < 0)
			continue;
		if (ioctl (fd, SIOCRESV, &af) >= 0)
			return (fd);
		else	{
			error = errno;
			close (fd);
			if (one_of (error, socketerrs, errct) >= 0) {
				errno = error;
				return (-1);
			}
			else	break;		/* return ENOBUFS */
		}
		
	}

	errno = ENOBUFS;
	return (-1);
}

static
one_of (guess, set, setsize)
register int *set;
{
	unix/servers/                                                                                          750     322     145            0  3621344622   6512                                                                                                                                                                                                                                                                                                                                                                      unix/servers/ftpd/                                                                                     750     322     145            0  3621344616   7452                                                                                                                                                                                                                                                                                                                                                                      unix/servers/ftpd/Makefile                                                                             444     322     145         1136  3621344612  11177                                                                                                                                                                                                                                                                                                                                                                       (   (  #	/*
#	 *	Copyright (c) 1984, Communication Machinery Corporation
#	 */
#	
#	/*
#	 *	This file contains material and information which is
#	 *	proprietary to Communication Machinery Corporation, and
#	 *	which may not be divulged without the express written
#	 *	permission of Communication Machinery Corporation.
#	 */

# Makefile 9/12/84
#
ALL=	ftpd.o glob.o vers.o ftpcmd.o interface.o
DESTDIR=.
CFLAGS= -O -I../../include
LIBS= -lcmcnet

ftpd:	${ALL}
	${CC} -o ftpd ${ALL} ${LIBS}
	chmod u+s ftpd

install:
	install -s ftpd ${DESTDIR}/etc/ftpd

clean:
	rm -f *.o *.s errs core a.out t.? yacc.* y.tab.c
(char *) lev;	/* non-standard use of where2 */
	pb->p_len2 = nm;		/* ditto for len2 */

	if ( ioctl (s, SIOCSOPT, pb) < 0 )
		return (-1);
	else	return (0);
}

getsockopt (s, lev, nm, val, len)
char *val;
int *len;
{
	userparm parm;
	register userparm *pb = &parm;

	pb->p_where = val;
	pb->p_len = (int) len;		/* non-standard use len */
	pb->p_where2 = (char *) lev;	/* non-standard use of where2 */
	pb->p_len2 = nm;unix/servers/ftpd/ftpcmd.y                                                                             444     322     145        33127  3621344613  11234                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * Grammar for FTP commands.
 * See RFC 765.
 */

%{

#ifndef lint
static char sccsid[] = "@(#)ftpcmd.y	5.0 (CMC) 09/28/84";
#endif

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>

#include <CMC/in.h>

#include <CMC/ftp.h>

#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#include <setjmp.h>

extern	struct sockaddr_in data_dest;
extern	int logged_in;
extern	struct passwd *pw;
extern	int guest;
extern	int logging;
extern	int type;
extern	int form;
extern	int debug;
extern	int timeout;
extern	char hostname[];
extern	char *globerr;
extern	int usedefault;
char	**glob();

static	int cmd_type;
static	int cmd_form;
static	int cmd_bytesz;

char	*strchr();
%}

%token
	A	B	C	E	F	I
	L	N	P	R	S	T

	SP	CRLF	COMMA	STRING	NUMBER

	USER	PASS	ACCT	REIN	QUIT	PORT
	PASV	TYPE	STRU	MODE	RETR	STOR
	APPE	MLFL	MAIL	MSND	MSOM	MSAM
	MRSQ	MRCP	ALLO	REST	RNFR	RNTO
	ABOR	DELE	CWD	LIST	NLST	SITE
	STAT	HELP	NOOP	XMKD	XRMD	XPWD
	XCUP

	LEXERR

%start	cmd_list

%%

cmd_list:	/* empty */
	|	cmd_list cmd
	;

cmd:		USER SP username CRLF
		= {
			extern struct passwd *getpwnam();

			if (strcmp($3, "ftp") == 0 ||
			  strcmp($3, "anonymous") == 0) {
				if ((pw = getpwnam("ftp")) != NULL) {
					guest = 1;
					reply(331,
				  "Guest login ok, send ident as password.");
				}
			} else if (checkuser($3)) {
				guest = 0;
				pw = getpwnam($3);
				reply(331, "Password required for %s.", $3);
			}
			if (pw == NULL)
				reply(530, "User %s unknown.", $3);
			free($3);
		}
	|	PASS SP password CRLF
		= {
			pass($3);
			free($3);
		}
	|	PORT SP host_port CRLF
		= {
			usedefault = 0;
			ack($1);
		}
	|	TYPE SP type_code CRLF
		= {
			switch (cmd_type) {

			case TYPE_A:
				if (cmd_form == FORM_N) {
					reply(200, "Type set to A.");
					type = cmd_type;
					form = cmd_form;
				} else
					reply(504, "Form must be N.");
				break;

			case TYPE_E:
				reply(504, "Type E not implemented.");
				break;

			case TYPE_I:
				reply(200, "Type set to I.");
				type = cmd_type;
				break;

			case TYPE_L:
				if (cmd_bytesz == 8) {
					reply(200,
					    "Type set to L (byte size 8).");
					type = cmd_type;
				} else
					reply(504, "Byte size must be 8.");
			}
		}
	|	STRU SP struct_code CRLF
		= {
			switch ($3) {

			case STRU_F:
				reply(200, "STRU F ok.");
				break;

			default:
				reply(502, "Unimplemented STRU type.");
			}
		}
	|	MODE SP mode_code CRLF
		= {
			switch ($3) {

			case MODE_S:
				reply(200, "MODE S ok.");
				break;

			default:
				reply(502, "Unimplemented MODE type.");
			}
		}
	|	ALLO SP NUMBER CRLF
		= {
			ack($1);
		}
	|	RETR check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				retrieve(0, $4);
			if ($4 != NULL)
				free($4);
		}
	|	STOR check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				store($4, "w");
			if ($4 != NULL)
				free($4);
		}
	|	APPE check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				store($4, "a");
			if ($4 != NULL)
				free($4);
		}
	|	NLST check_login CRLF
		= {
			if ($2)
				retrieve("/bin/ls", "");
		}
	|	NLST check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				retrieve("/bin/ls %s", $4);
			if ($4 != NULL)
				free($4);
		}
	|	LIST check_login CRLF
		= {
			if ($2)
				retrieve("/bin/ls -lg", "");
		}
	|	LIST check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				retrieve("/bin/ls -lg %s", $4);
			if ($4 != NULL)
				free($4);
		}
	|	DELE check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				delete($4);
			if ($4 != NULL)
				free($4);
		}
	|	CWD check_login CRLF
		= {
			if ($2)
				cwd(pw->pw_dir);
		}
	|	CWD check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				cwd($4);
			if ($4 != NULL)
				free($4);
		}
	|	rename_cmd
	|	HELP CRLF
		= {
			help(0);
		}
	|	HELP SP STRING CRLF
		= {
			help($3);
		}
	|	NOOP CRLF
		= {
			ack($1);
		}
	|	XMKD check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				makedir($4);
			if ($4 != NULL)
				free($4);
		}
	|	XRMD check_login SP pathname CRLF
		= {
			if ($2 && $4 != NULL)
				removedir($4);
			if ($4 != NULL)
				free($4);
		}
	|	XPWD check_login CRLF
		= {
			if ($2)
				pwd();
		}
	|	XCUP check_login CRLF
		= {
			if ($2)
				cwd("..");
		}
	|	QUIT CRLF
		= {
			reply(221, "Goodbye.");
			dologout(0);
		}
	|	error CRLF
		= {
			yyerrok;
		}
	;

username:	STRING
	;

password:	STRING
	;

byte_size:	NUMBER
	;

host_port:	NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA 
		NUMBER COMMA NUMBER
		= {
			register char *a, *p;

			a = (char *)&data_dest.sin_addr;
			a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7;
			p = (char *)&data_dest.sin_port;
			p[0] = $9; p[1] = $11;
			data_dest.sin_family = AF_INET;
		}
	;

form_code:	N
	= {
		$$ = FORM_N;
	}
	|	T
	= {
		$$ = FORM_T;
	}
	|	C
	= {
		$$ = FORM_C;
	}
	;

type_code:	A
	= {
		cmd_type = TYPE_A;
		cmd_form = FORM_N;
	}
	|	A SP form_code
	= {
		cmd_type = TYPE_A;
		cmd_form = $3;
	}
	|	E
	= {
		cmd_type = TYPE_E;
		cmd_form = FORM_N;
	}
	|	E SP form_code
	= {
		cmd_type = TYPE_E;
		cmd_form = $3;
	}
	|	I
	= {
		cmd_type = TYPE_I;
	}
	|	L
	= {
		cmd_type = TYPE_L;
		cmd_bytesz = 8;
	}
	|	L SP byte_size
	= {
		cmd_type = TYPE_L;
		cmd_bytesz = $3;
	}
	/* this is for a bug in the BBN ftp */
	|	L byte_size
	= {
		cmd_type = TYPE_L;
		cmd_bytesz = $2;
	}
	;

struct_code:	F
	= {
		$$ = STRU_F;
	}
	|	R
	= {
		$$ = STRU_R;
	}
	|	P
	= {
		$$ = STRU_P;
	}
	;

mode_code:	S
	= {
		$$ = MODE_S;
	}
	|	B
	= {
		$$ = MODE_B;
	}
	|	C
	= {
		$$ = MODE_C;
	}
	;

pathname:	pathstring
	= {
		if ($1 && strncmp($1, "~", 1) == 0) {
			$$ = (int)*glob($1);
			if (globerr != NULL) {
				reply(550, globerr);
				$$ = NULL;
			}
			free($1);
		} else
			$$ = $1;
	}
	;

pathstring:	STRING
	;

rename_cmd:	rename_from rename_to
	= {
		if ($1 && $2)
			renamecmd($1, $2);
		else
			reply(503, "Bad sequence of commands.");
		if ($1)
			free($1);
		if ($2)
			free($2);
	}
	;

rename_from:	RNFR check_login SP pathname CRLF
	= {
		char *from = 0, *renamefrom();

		if ($2 && $4)
			from = renamefrom($4);
		if (from == 0 && $4)
			free($4);
		$$ = (int)from;
	}
	;

rename_to:	RNTO SP pathname CRLF
	= {
		$$ = $3;
	}
	;

check_login:	/* empty */
	= {
		if (logged_in)
			$$ = 1;
		else {
			reply(530, "Please login with USER and PASS.");
			$$ = 0;
		}
	}
	;

%%

extern jmp_buf errcatch;

#define	CMD	0	/* beginning of command */
#define	ARGS	1	/* expect miscellaneous arguments */
#define	STR1	2	/* expect SP followed by STRING */
#define	STR2	3	/* expect STRING */
#define	OSTR	4	/* optional STRING */

struct tab {
	char	*name;
	short	token;
	short	state;
	short	implemented;	/* 1 if command is implemented */
	char	*help;
};

struct tab cmdtab[] = {		/* In order defined in RFC 765 */
	{ "USER", USER, STR1, 1,	"<sp> username" },
	{ "PASS", PASS, STR1, 1,	"<sp> password" },
	{ "ACCT", ACCT, STR1, 0,	"(specify account)" },
	{ "REIN", REIN, ARGS, 0,	"(reinitialize server state)" },
	{ "QUIT", QUIT, ARGS, 1,	"(terminate service)", },
	{ "PORT", PORT, ARGS, 1,	"<sp> b0, b1, b2, b3, b4" },
	{ "PASV", PASV, ARGS, 0,	"(set server in passive mode)" },
	{ "TYPE", TYPE, ARGS, 1,	"<sp> [ A | E | I | L ]" },
	{ "STRU", STRU, ARGS, 1,	"(specify file structure)" },
	{ "MODE", MODE, ARGS, 1,	"(specify transfer mode)" },
	{ "RETR", RETR, STR1, 1,	"<sp> file-name" },
	{ "STOR", STOR, STR1, 1,	"<sp> file-name" },
	{ "APPE", APPE, STR1, 1,	"<sp> file-name" },
	{ "MLFL", MLFL, OSTR, 0,	"(mail file)" },
	{ "MAIL", MAIL, OSTR, 0,	"(mail to user)" },
	{ "MSND", MSND, OSTR, 0,	"(mail send to terminal)" },
	{ "MSOM", MSOM, OSTR, 0,	"(mail send to terminal or mailbox)" },
	{ "MSAM", MSAM, OSTR, 0,	"(mail send to terminal and mailbox)" },
	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
	{ "REST", REST, STR1, 0,	"(restart command)" },
	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
	{ "ABOR", ABOR, ARGS, 0,	"(abort operation)" },
	{ "DELE", DELE, STR1, 1,	"<sp> file-name" },
	{ "CWD",  CWD,  OSTR, 1,	"[ <sp> directory-name]" },
	{ "XCWD", CWD,	OSTR, 1,	"[ <sp> directory-name ]" },
	{ "LIST", LIST, OSTR, 1,	"[ <sp> path-name ]" },
	{ "NLST", NLST, OSTR, 1,	"[ <sp> path-name ]" },
	{ "SITE", SITE, STR1, 0,	"(get site parameters)" },
	{ "STAT", STAT, OSTR, 0,	"(get server status)" },
	{ "HELP", HELP, OSTR, 1,	 (   (  "[ <sp> <string> ]" },
	{ "NOOP", NOOP, ARGS, 1,	"" },
	{ "XMKD", XMKD, STR1, 1,	"<sp> path-name" },
	{ "XRMD", XRMD, STR1, 1,	"<sp> path-name" },
	{ "XPWD", XPWD, ARGS, 1,	"return current directory" },
	{ "XCUP", XCUP, ARGS, 1,	"change to parent directory" },
	{ NULL,   0,    0,    0,	0 }
};

struct tab *
lookup(cmd)
	char *cmd;
{
	register struct tab *p;

	for (p = cmdtab; p->name != NULL; p++)
		if (strcmp(cmd, p->name) == 0)
			return (p);
	return (0);
}

#include <CMC/telnet.h>

/*
 * getline - a hacked up version of fgets to ignore TELNET escape codes.
 */
char *
getline(s, n, iop)
	char *s;
	register FILE *iop;
{
	register c;
	register char *cs;

	cs = s;
	while (--n > 0 && (c = getc(iop)) >= 0) {
		while (c == IAC) {
			c = getc(iop);	/* skip command */
			c = getc(iop);	/* try next char */
		}
		*cs++ = c;
		if (c=='\n')
			break;
	}
	if (c < 0 && cs == s)
		return (NULL);
	*cs++ = '\0';
	if (debug) {
		fprintf(stderr, "FTPD: command: %s", s);
		if (c != '\n')
			putc('\n', stderr);
		fflush(stderr);
	}
	return (s);
}

static int
toolong()
{
	long now;
	extern char *ctime();

	reply(421,
	  "Timeout (%d seconds): closing control connection.", timeout);
	time(&now);
	if (logging) {
		fprintf(stderr,
			"FTPD: User %s timed out after %d seconds at %s",
			(pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
		fflush(stderr);
	}
	dologout(1);
}

yylex()
{
	static char cbuf[512];
	static int cpos, state;
	register char *cp;
	register struct tab *p;
	int n;
	char c;

	for (;;) {
		switch (state) {

		case CMD:
			signal(SIGALRM, toolong);
			alarm(timeout);
			if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
				reply(221, "You could at least say goodbye.");
				dologout(0);
			}
			alarm(0);
			if (strchr(cbuf, '\r')) {
				cp = strchr(cbuf, '\r');
				cp[0] = '\n'; cp[1] = 0;
			}
			if (strchr(cbuf, ' '))
				cpos = strchr(cbuf, ' ') - cbuf;
			else
				cpos = 4;
			c = cbuf[cpos];
			cbuf[cpos] = '\0';
			upper(cbuf);
			p = lookup(cbuf);
			cbuf[cpos] = c;
			if (p != 0) {
				if (p->implemented == 0) {
					nack(p->name);
					longjmp(errcatch);
					/* NOTREACHED */
				}
				state = p->state;
				yylval = (int) p->name;
				return (p->token);
			}
			break;

		case OSTR:
			if (cbuf[cpos] == '\n') {
				state = CMD;
				return (CRLF);
			}
			/* FALL THRU */

		case STR1:
			if (cbuf[cpos] == ' ') {
				cpos++;
				state = STR2;
				return (SP);
			}
			break;

		case STR2:
			cp = &cbuf[cpos];
			n = strlen(cp);
			cpos += n - 1;
			/*
			 * Make sure the string is nonempty and \n terminated.
			 */
			if (n > 1 && cbuf[cpos] == '\n') {
				cbuf[cpos] = '\0';
				yylval = copy(cp);
				cbuf[cpos] = '\n';
				state = ARGS;
				return (STRING);
			}
			break;

		case ARGS:
			if (isdigit(cbuf[cpos])) {
				cp = &cbuf[cpos];
				while (isdigit(cbuf[++cpos]))
					;
				c = cbuf[cpos];
				cbuf[cpos] = '\0';
				yylval = atoi(cp);
				cbuf[cpos] = c;
				return (NUMBER);
			}
			switch (cbuf[cpos++]) {

			case '\n':
				state = CMD;
				return (CRLF);

			case ' ':
				return (SP);

			case ',':
				return (COMMA);

			case 'A':
			case 'a':
				return (A);

			case 'B':
			case 'b':
				return (B);

			case 'C':
			case 'c':
				return (C);

			case 'E':
			case 'e':
				return (E);

			case 'F':
			case 'f':
				return (F);

			case 'I':
			case 'i':
				return (I);

			case 'L':
			case 'l':
				return (L);

			case 'N':
			case 'n':
				return (N);

			case 'P':
			case 'p':
				return (P);

			case 'R':
			case 'r':
				return (R);

			case 'S':
			case 's':
				return (S);

			case 'T':
			case 't':
				return (T);

			}
			break;

		default:
			fatal("Unknown state in scanner.");
		}
		yyerror();
		state = CMD;
		longjmp(errcatch);
	}
}

upper(s)
	char *s;
{
	while (*s != '\0') {
		if (islower(*s))
			*s = toupper(*s);
		s++;
	}
}

copy(s)
	char *s;
{
	char *p;
	extern char *malloc();

	p = malloc(strlen(s) + 1);
	if (p == NULL)
		fatal("Ran out of memory.");
	strcpy(p, s);
	return ((int)p);
}

help(s)
	char *s;
{
	register struct tab *c;
	register int width, NCMDS;

	width = 0, NCMDS = 0;
	for (c = cmdtab; c->name != NULL; c++) {
		int len = strlen(c->name);

		if (c->implemented == 0)
			len++;
		if (len > width)
			width = len;
		NCMDS++;
	}
	width = (width + 8) &~ 7;
	if (s == 0) {
		register int i, j, w;
		int columns, lines;

		lreply(214,
	  "The following commands are recognized (* =>'s unimplemented).");
		columns = 76 / width;
		if (columns == 0)
			columns = 1;
		lines = (NCMDS + columns - 1) / columns;
		for (i = 0; i < lines; i++) {
			printf("    ");
			for (j = 0; j < columns; j++) {
				c = cmdtab + j * lines + i;
				printf("%s%c", c->name,
					c->implemented ? ' ' : '*');
				if (c + lines >= &cmdtab[NCMDS])
					break;
				w = strlen(c->name);
				while (w < width) {
					putchar(' ');
					w++;
				}
			}
			printf("\r\n");
		}
		fflush(stdout);
		reply(214, "Direct comments to ftp-bugs@%s.", hostname);
		return;
	}
	upper(s);
	c = lookup(s);
	if (c == (struct tab *)0) {
		reply(504, "Unknown command %s.", s);
		return;
	}
	if (c->implemented)
		reply(214, "Syntax: %s %s", c->name, c->help);
	else
		reply(214, "%-*s\t%s; unimplemented.", width, c->name, c->help);
}
orm = $3;
	}
	|	E
	= {
		cmd_type = TYPE_E;
		cmd_form = FORM_N;
	}
	|	E SP form_code
	= {
		cmd_type = TYPE_E;
		cmd_form = $3;
	}
	|	I
	= {
		cmd_type = TYPE_I;
	}
	|	L
	= {
		cmd_type = TYPE_L;
		cmd_bytesz = 8;
	}
	|	L SP byte_size
	= {
		cmd_type = TYPE_L;
		cmd_bytesz = $3;
	}
	/* this is for a bug in the BBN ftp */
	|	L byte_size
	= {
		cmd_type = TYPE_L;
		cmd_bytesz = $2;
	}
	;

struct_code:	F
	= {
		$$ = STRU_F;unix/servers/ftpd/ftpd.c                                                                               444     322     145        45462  3621344614  10674                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)ftpd.c	5.0 (CMC) 9/22/83";
#endif

/*
 * FTP server.
 *
 * 17 August 1984 - Changed name global "sp" to "servp" to get around bug
 *	in assem.  (It thinks our "sp" is it's stack pointer!)
 *					Deb Brown, CMC
 * 24 August 1984 - Modified to ignore SIGCHLD signals, so child processes
 *	will go away when they die without our using the wait3 system call,
 *	which isn't supported on System V.		Deb Brown, CMC
 *
 * September, 1984 -- Completed System V conversion	John Mullen
 */

#include <CMC/sysdep.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/param.h>
#include <sys/stat.h>
#include <CMC/socket.h>
#include <fcntl.h>

#include <CMC/in.h>

#include <CMC/ftp.h>
#include <CMC/inet.h>

#include <stdio.h>
#include <CMC/signal.h>
#include <pwd.h>
#include <setjmp.h>
#include <CMC/netdb.h>
#include <CMC/errno.h>

#ifndef SIGCHLD
#define SIGCHLD	SIGCLD
#endif

/*
 * File containing login names
 * NOT to be used on this machine.
 * Commonly used to disallow uucp.
 */
#define	FTPUSERS	"/etc/ftpusers"

/*	File to store login records	*/
# define WTMP	"/usr/adm/wtmp"

extern	int errno;
extern	char *net_error();
extern	char *crypt();
extern	char version[];
extern	char *home;		/* pointer to home directory for glob */
extern	FILE *Popen(), *fopen();
extern	int Pclose(), fclose();

struct	sockaddr_in ctrl_addr = {AF_INET};
struct	sockaddr_in data_source;
struct	sockaddr_in data_dest;
struct	sockaddr_in his_addr;

struct	hostent *hp;

int	data;
jmp_buf	errcatch;
int	logged_in;
struct	passwd *pw;
int	debug;
int	timeout;
int	logging;
int	guest;
int	type;
int	form;
int	stru;			/* avoid C keyword */
int	mode;
int	usedefault = 1;		/* for data transfers */
char	hostname[32];
char	remotehost[32];
struct	servent *servp;

/*
 * Timeout intervals for retrying connections
 * to hosts that don't accept PORT cmds.  This
 * is a kludge, but given the problems with TCP...
 */
#define	SWAITMAX	90	/* wait at most 90 seconds */
#define	SWAITINT	5	/* interval between retries */

int	swaitmax = SWAITMAX;
int	swaitint = SWAITINT;

int	lostconn();
int	reapchild();
FILE	*getdatasock(), *dataconn();

main(argc, argv)
	int argc;
	char *argv[];
{
	int ctrl, s, options = 0;
	int ctrl_len;
	char *cp;

	servp = getservbyname("ftp", "tcp");
	if (servp == 0) {
		fprintf(stderr, "ftpd: ftp/tcp: unknown service\n");
		exit(1);
	}
	ctrl_addr.sin_port = servp->s_port;
	data_source.sin_port = htons(ntohs(servp->s_port) - 1);
	signal(SIGPIPE, lostconn);
	debug = 0;
	argc--, argv++;
	while (argc > 0 && *argv[0] == '-') {
		for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {

		case 'v':
			debug = 1;
			break;

		case 'd':
			debug = 1;
			options |= SO_DEBUG;
			break;

		case 'l':
			logging = 1;
			break;

		case 't':
			timeout = atoi(++cp);
			goto nextopt;
			break;

		default:
			fprintf(stderr, "Unknown flag -%c ignored.\n", *cp);
			break;
		}
nextopt:
		argc--, argv++;
	}
#ifndef DEBUG
	if (fork())
		exit(0);
	for (s = 0; s < 10; s++)
		if (!logging || (s != 2))
			(void) close(s);
	(void) open("/", O_RDONLY);
	fcntl(0, F_DUPFD, 1);
	if (!logging)
		fcntl(0, F_DUPFD, 2);
	setpgrp();
#endif
	while ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("ftpd: socket");
		sleep(5);
	}
	if (options & SO_DEBUG)
		if (setsockopt(s, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
			perror("ftpd: setsockopt (SO_DEBUG)");
	if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
		perror("ftpd: setsockopt (SO_KEEPALIVE)");
	while (bind(s, &ctrl_addr, sizeof (ctrl_addr)) < 0) {
		perror("ftpd: bind");
		sleep(5);
	}
	if (debug) {
		fprintf (stderr, "FTPD: control socket is (%s,%d)\n",
			inet_ntoa(ctrl_addr.sin_addr),
			ntohs (ctrl_addr.sin_port));
		fflush (stderr);
	}
	signal(SIGCHLD, reapchild);
	signal(SIGURGENT, SIG_IGN);
	listen(s, 1 (   (  0);
	for (;;) {
		int hisaddrlen = sizeof (his_addr);

		ctrl = accept(s, &his_addr, &hisaddrlen);
		if (ctrl < 0) {
			if (errno == EINTR)
				continue;
			perror("ftpd: accept");
			continue;
		}
		if (fork() == 0) {
			setpgrp ();
			signal (SIGCHLD, SIG_DFL);
			dolog(&his_addr);
			close(s);
			close(0);
			close(1);
			fcntl(ctrl, F_DUPFD, 0);
			fcntl(0, F_DUPFD, 1);
			close(ctrl);
			/* do telnet option negotiation here */
			/*
			 * Set up default state
			 */
			logged_in = 0;
			data = -1;
			type = TYPE_A;
			form = FORM_N;
			stru = STRU_F;
			mode = MODE_S;
			(void) getsockname(0, &ctrl_addr, &ctrl_len);
			gethostname(hostname, sizeof (hostname));
			reply(220, "%s FTP server (%s) ready.",
				hostname, version);
			for (;;) {
				setjmp(errcatch);
				yyparse();
			}
		}
		close(ctrl);
	}
}

reapchild()
{
	register pid;
	int stat;

	pid = wait(&stat);
	if (debug && (pid != -1))
		fprintf (stderr, "FTPD: child %d died: %x+%x\n", pid,
			(stat>>8)&0xFF, stat&0xFF);
	signal(SIGCHLD, reapchild);
}

lostconn()
{

	if (debug)
		fprintf(stderr, "Lost connection.\n");
	dologout(-1);
}

pass(passwd)
	char *passwd;
{
	char *xpasswd, *savestr();
	static struct passwd save;

	if (logged_in || pw == NULL) {
		reply(503, "Login with USER first.");
		return;
	}
	if (!guest) {		/* "ftp" is only account allowed no password */
		xpasswd = crypt(passwd, pw->pw_passwd);
		if (*pw->pw_passwd == '\0' || strcmp(xpasswd, pw->pw_passwd)) {
			reply(530, "Login incorrect.");
			pw = NULL;
			return;
		}
	}
	setgid(pw->pw_gid);
	if (chdir(pw->pw_dir)) {
		reply(550, "User %s: can't change directory to $s.",
			pw->pw_name, pw->pw_dir);
		goto bad;
	}
	if (guest && chroot(pw->pw_dir) < 0) {
		reply(550, "Can't set guest privileges.");
		goto bad;
	}
	if (!guest)
		reply(230, "User %s logged in.", pw->pw_name);
	else
		reply(230, "Guest login ok, access restrictions apply.");
	logged_in = 1;
	dologin(pw);
/* seteuid(pw->pw_uid); */
	/*
	 * Save everything so globbing doesn't
	 * clobber the fields.
	 */
	save = *pw;
	save.pw_name = savestr(pw->pw_name);
	save.pw_passwd = savestr(pw->pw_passwd);
	save.pw_comment = savestr(pw->pw_comment);
	save.pw_gecos = savestr(pw->pw_gecos, &save.pw_gecos);
	save.pw_dir = savestr(pw->pw_dir);
	save.pw_shell = savestr(pw->pw_shell);
	pw = &save;
	home = pw->pw_dir;		/* home dir for globbing */
	return;
bad:
/* seteuid(0); */
	pw = NULL;
}

char *
savestr(s)
	char *s;
{
	char *malloc();
	char *new = malloc(strlen(s) + 1);
	
	if (new != NULL)
		strcpy(new, s);
	return (new);
}

retrieve(cmd, name)
	char *cmd, *name;
{
	FILE *fin, *dout;
	struct stat st;
	int (*closefunc)();

	if (cmd == 0) {
#ifdef notdef
		/* no remote command execution -- it's a security hole */
		if (*name == '|')
			fin = Popen(name + 1, "r"), closefunc = Pclose;
		else
#endif
			fin = fopen(name, "r"), closefunc = fclose;
	} else {
		char line[BUFSIZ];

		sprintf(line, cmd, name), name = line;
		fin = Popen(line, "r"), closefunc = Pclose;
	}
	if (fin == NULL) {
		if (errno != 0)
			reply(550, "%s: %s.", name, net_error(errno));
		return;
	}
	st.st_size = 0;
	if (cmd == 0) {
		if ( !accessible (name, 04) ) {	/* file readable? */
			reply (550, "%s: %s.", name, net_error(errno));
			goto done;
		}
		if (stat(name, &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) {
			reply(550, "%s: not a plain file.", name);
			goto done;
		}
	}
	dout = dataconn(name, st.st_size, "w");
	if (dout == NULL)
		goto done;
	if (send_data(fin, dout) || ferror(dout))
		reply(550, "%s: %s.", name, net_error(errno));
	else
		reply(226, "Transfer complete.");
	fclose(dout), data = -1;
done:
	(*closefunc)(fin);
}

store(name, mode)
	char *name, *mode;
{
	FILE *fout, *din;
	int (*closefunc)(), dochown = 0;

#ifdef notdef
	/* no remote command execution -- it's a security hole */
	if (name[0] == '|')
		fout = Popen(&name[1], "w"), closefunc = Pclose;
	else
#endif
	{
		struct stat st;

		if ( (! accessible (parent(name, 02)))
		    || ( accessible (name,0) && !accessible (name, 02)) ) {
			reply (550, "%s: %s.", name, net_error(errno));
			return ( -1 );
		}
		if (stat(name, &st) < 0)
			dochown++;
		fout = fopen(name, mode), closefunc = fclose;
	}
	if (fout == NULL) {
		reply(550, "%s: %s.", name, net_error(errno));
		return;
	}
	din = dataconn(name, (off_t)-1, "r");
	if (din == NULL)
		goto done;
	if (receive_data(din, fout) || ferror(fout))
		reply(550, "%s: %s.", name, net_error(errno));
	else
		reply(226, "Transfer complete.");
	fclose(din), data = -1;
done:
	if (dochown)
		(void) chown(name, pw->pw_uid, pw->pw_gid);
	(*closefunc)(fout);
}

FILE *
getdatasock(mode)
	char *mode;
{
	int s;

	if (data >= 0)
		return (fdopen(data, mode));
	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s < 0)
		return (NULL);
/* seteuid(0); */
	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
		goto bad;
	/* anchor socket to avoid multi-homing problems */
	data_source.sin_family = AF_INET;
	data_source.sin_addr = ctrl_addr.sin_addr;
	if (bind(s, &data_source, sizeof (data_source)) < 0)
		goto bad;
/* seteuid(pw->pw_uid); */
	return (fdopen(s, mode));
bad:
/* seteuid(pw->pw_uid); */
	close(s);
	return (NULL);
}

FILE *
dataconn(name, size, mode)
	char *name;
	off_t size;
	char *mode;
{
	char sizebuf[32];
	FILE *file;
	int retry = 0;

	if (size >= 0)
		sprintf (sizebuf, " (%ld bytes)", size);
	else
		(void) strcpy(sizebuf, "");
	if (data >= 0) {
		reply(125, "Using existing data connection for %s%s.",
		    name, sizebuf);
		usedefault = 1;
		return (fdopen(data, mode));
	}
	if (usedefault)
		data_dest = his_addr;
	usedefault = 1;
	file = getdatasock(mode);
	if (file == NULL) {
		reply(425, "Can't create data socket (%s,%d): %s.",
		    inet_ntoa(data_source.sin_addr),
		    ntohs(data_source.sin_port),
		    net_error(errno));
		return (NULL);
	}
	reply(150, "Opening data connection for %s (%s,%d)%s.",
	    name, inet_ntoa(data_dest.sin_addr.s_addr),
	    ntohs(data_dest.sin_port), sizebuf);
	data = fileno(file);
	while (connect(data, &data_dest, sizeof (data_dest)) < 0) {
		if (errno == EADDRINUSE && retry < swaitmax) {
			sleep(swaitint);
			retry += swaitint;
			continue;
		}
		reply(425, "Can't build data connection: %s.",
		    net_error(errno));
		(void) fclose(file);
		data = -1;
		return (NULL);
	}
	return (file);
}

/*
 * Tranfer the contents of "instr" to
 * "outstr" peer using the appropriate
 * encapulation of the date subject
 * to Mode, Structure, and Type.
 *
 * NB: Form isn't handled.
 */
send_data(instr, outstr)
	FILE *instr, *outstr;
{
	register int c;
	int netfd, filefd, cnt;
	char buf[BUFSIZ];

	switch (type) {

	case TYPE_A:
		while ((c = getc(instr)) != EOF) {
			if (c == '\n') {
				if (ferror (outstr))
					return (1);
				putc('\r', outstr);
			}
			putc(c, outstr);
			if (c == '\r')
				putc ('\0', outstr);
		}
		if (ferror (instr) || ferror (outstr))
			return (1);
		return (0);
		
	case TYPE_I:
	case TYPE_L:
		netfd = fileno(outstr);
		filefd = fileno(instr);

		while ((cnt = read(filefd, buf, sizeof (buf))) > 0)
			if (write(netfd, buf, cnt) < 0)
				return (1);
		return (cnt < 0);
	}
	reply(504,"Unimplemented TYPE %d in send_data", type);
	return (1);
}

/*
 * Transfer data from peer to
 * "outstr" using the appropriate
 * encapulation of the data subject
 * to Mode, Structure, and Type.
 *
 * N.B.: Form isn't handled.
 */
receive_data(instr, outstr)
	FILE *instr, *outstr;
{
	register int c;
	int cnt;
	char buf[BUFSIZ];


	switch (type) {

	case TYPE_I:
	case TYPE_L:
		while ((cnt = read(fileno(instr), buf, sizeof buf)) > 0)
			if (write(fileno(outstr), buf, cnt) < 0)
				return (1);
		return (cnt < 0);

	case TYPE_E:
		reply(504, "TYPE E not implemented.");
		return (1);

	case TYPE_A:
		while ((c = getc(instr)) != EOF) {
			if (c == '\r') {
				if (ferror (outstr))
					return (1);
				if ((c = getc(instr)) != '\n')
					putc ('\r', outstr);
				if (c == '\0')
					continue;
			}
			putc (c, outstr);
		}
		if (ferror (instr) || ferror (outstr))
			return (1);
		return (0);
	}
	fatal("Unknown type in receive_data.");
	/*NOTREACHED*/
}

fatal(s)
	char *s;
{
	reply(451, "Error in server: %s\n", s);
	reply(221, "Closing connection due to server error.");
	dologout(0);
}

reply(n, s, args)
	int n;
	char *s;
{

	printf("%d ", n);
	_doprnt(s, &args, stdout);
	printf("\r\n");
	fflush(stdout);
	if (debug) {
		fprintf(stderr, "<--- %d ", n);
		_doprnt(s, &args, stderr);
		fprintf(stderr, "\n");
		fflush(stderr);
	}
}

lreply(n, s, args)
	int n;
	char *s;
{
	printf("%d-", n);
	_doprnt(s, &args, stdout);
	printf("\r\n");
	fflush(stdout);
	if (debug) {
		fprintf(stderr, "<--- %d-", n);
		_doprnt(s, &args, stderr);
		fprintf(stderr, "\n");
	}
}

replystr(s)
	char *s;
{
	printf("%s\r\n", s);
	fflush(stdout);
	if (debug)
		fprintf(stderr, "<--- %s\n", s);
}

ack(s)
	char *s;
{
	reply(200, "%s command okay.", s);
}

nack(s)
	char *s;
{
	reply(502, "%s command not implemented.", s);
}

yyerror()
{
	reply(500, "Command not understood.");
}

delete(name)
	char *name;
{
	struct stat st;

	if ( (! accessible (parent(name, 02)))
	    || ( accessible (name,0) && !accessible (name, 02)) ) {
		reply (550, "%s: %s.", name, net_error(errno));
		return ( -1 );
	}
	if (stat(name, &st) < 0) {
		reply(550, "%s: %s.", name, net_error(errno));
		return;
	}
	if ((st.st_mode&S_IFMT) == S_IFDIR) {
		if (rmdir(name) < 0) {
			reply(550, "%s: %s.", name, net_error(errno));
			return;
		}
		goto done;
	}
	if (unlink(name) < 0) {
		reply(550, "%s: %s.", name, net_error(errno));
		return;
	}
done:
	ack("DELE");
}

cwd(path)
	char *path;
{

	if (chdir(path) < 0) {
		reply(550, "%s: %s.", path, net_error(errno));
		return;
	}
	ack("CWD");
}

makedir(name)
	char *name;
{
	struct stat st;
	int dochown = stat(name, &st) < 0;
	
	if ( (! accessible (parent(name, 02))) || accessible (name,0) )  {
		reply (550, "%s: %s.", name, net_error(errno));
		return ( -1 );
	}
	if (mkdir(name, 0777) < 0) {
		reply(550, "%s: %s.", name, net_error(errno));
		return;
	}
	if (dochown)
		(void) chown(name, pw->pw_uid, pw->pw_gid);
	ack("MKDIR");
}

removedir(name)
	char *name;
{

	if ( !accessible (parent(name), 02) ) {
		reply (550, "%s: %s.", name, net_error(errno));
		return;
	}
	if (rmdir(name) < 0) {
		reply(550, "%s: %s.", name, ne (   (  t_error(errno));
		return;
	}
	ack("RMDIR");
}

pwd()
{
	register char *path;
	extern char *getcwd();

	if ((path = getcwd(NULL, 128+2)) == NULL) {
		reply(451, "Cannot determine current directory.");
		perror ("getcwd");
		return;
	}
	reply(251, "\"%s\" is current directory.", path);
	free (path);
}

char *
renamefrom(name)
	char *name;
{
	struct stat st;

	if ( (!accessible(parent(name), 02)) || (stat(name, &st) < 0) ) {
		reply(550, "%s: %s.", name, net_error(errno));
		return ((char *)0);
	}
	reply(350, "File exists, ready for destination name");
	return (name);
}

renamecmd(from, to)
	char *from, *to;
{

	if ( !accessible (parent (to), 02) ) {
		reply (550, "rename: %s: %s", to, net_error(errno));
		return;
	}
	if (rename(from, to) < 0) {
		reply(550, "rename: %s.", net_error(errno));
		return;
	}
	ack("RNTO");
}

dolog(sin)
	struct sockaddr_in *sin;
{
	struct hostent *hp = gethostbyaddr(&sin->sin_addr,
		sizeof (struct in_addr), AF_INET);
	time_t t;

	if (hp) {
		strncpy(remotehost, hp->h_name, sizeof (remotehost));
		endhostent();
	} else
		strncpy(remotehost, inet_ntoa(sin->sin_addr),
		    sizeof (remotehost));
	if (!logging)
		return;
	t = time(0);
	fprintf(stderr,"FTPD: connection from %s at %s", remotehost, ctime(&t));
	fflush(stderr);
}

#include <utmp.h>

#define	SCPYN(a, b)	strncpy(a, b, sizeof (a))
struct	utmp utmp;

/*
 * Record login in wtmp file.
 */
dologin(pw)
	struct passwd *pw;
{
	int wtmp;
	char line[32];

	wtmp = open(WTMP, O_WRONLY|O_APPEND);
	if (wtmp >= 0) {
		/* hack, but must be unique and no tty line */
		sprintf(line, "ftp%d", getpid());
		SCPYN(utmp.ut_line, line);
		SCPYN(utmp.ut_name, pw->pw_name);
# ifdef notdef
		utmp.ut_pid = getpid();
		utmp.ut_type = USER_PROCESS;
# endif notdef
		utmp.ut_time = time(0);
		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
		(void) close(wtmp);
	}
}

/*
 * Record logout in wtmp file
 * and exit with supplied status.
 */
dologout(status)
	int status;
{
	int wtmp;

	if (!logged_in)
		_exit(status);
/* seteuid(0); */
	wtmp = open(WTMP, O_WRONLY|O_APPEND);
	if (wtmp >= 0) {
		SCPYN(utmp.ut_name, "");
# ifdef notdef
		utmp.ut_type = DEAD_PROCESS;
# endif notdef
		utmp.ut_time = time(0);
		(void) write(wtmp, (char *)&utmp, sizeof (utmp));
		(void) close(wtmp);
	}
	/* beware of flushing buffers after a SIGPIPE */
	_exit(status);
}

/*
 * Special version of popen which avoids
 * call to shell.  This insures noone may 
 * create a pipe to a hidden program as a side
 * effect of a list or dir command.
 */
#define	tst(a,b)	(*mode == 'r'? (b) : (a))
#define	RDR	0
#define	WTR	1
static	int Popen_pid[5];

static char *
nextarg(cpp)
	char *cpp;
{
	register char *cp = cpp;

	if (cp == 0)
		return (cp);
	while (*cp && *cp != ' ' && *cp != '\t')
		cp++;
	if (*cp == ' ' || *cp == '\t') {
		*cp++ = '\0';
		while (*cp == ' ' || *cp == '\t')
			cp++;
	}
	if (cp == cpp)
		return ((char *)0);
	return (cp);
}

FILE *
Popen(cmd, mode)
	char *cmd, *mode;
{
	int p[2], ac, gac;
	register myside, hisside, pid;
	char *av[20], *gav[512];
	register char *cp;

	if (pipe(p) < 0)
		return (NULL);
	cp = cmd, ac = 0;
	/* break up string into pieces */
	do {
		av[ac++] = cp;
		cp = nextarg(cp);
	} while (cp && *cp && ac < 20);
	av[ac] = (char *)0;
	gav[0] = av[0];
	/* glob each piece */
	for (gac = ac = 1; av[ac] != NULL; ac++) {
		char **pop;
		extern char **glob();

		pop = glob(av[ac]);
		if (pop) {
			av[ac] = (char *)pop;		/* save to free later */
			while (*pop && gac < 512)
				gav[gac++] = *pop++;
		}
	}
	gav[gac] = (char *)0;
	myside = tst(p[WTR], p[RDR]);
	hisside = tst(p[RDR], p[WTR]);
	if ((pid = fork()) == 0) {
		/* myside and hisside reverse roles in child */
		close(myside);
		(void) close(tst(0, 1));
		fcntl(hisside, F_DUPFD, tst(0, 1));
		close(hisside);
		execv(gav[0], gav);
		_exit(1);
	}
	for (ac = 1; av[ac] != NULL; ac++)
		blkfree((char **)av[ac]);
	if (pid == -1)
		return (NULL);
	Popen_pid[myside] = pid;
	close(hisside);
	return (fdopen(myside, mode));
}

Pclose(ptr)
	FILE *ptr;
{
	register f, r, (*hstat)(), (*istat)(), (*qstat)();
	int status;

	f = fileno(ptr);
	fclose(ptr);
	istat = signal(SIGINT, SIG_IGN);
	qstat = signal(SIGQUIT, SIG_IGN);
	hstat = signal(SIGHUP, SIG_IGN);
	while ((r = wait(&status)) != Popen_pid[f] && r != -1)
		;
	if (r == -1)
		status = -1;
	signal(SIGINT, istat);
	signal(SIGQUIT, qstat);
	signal(SIGHUP, hstat);
	return (status);
}

/*
 * Check user requesting login priviledges.
 * Disallow anyone mentioned in the file FTPUSERS
 * to allow people such as uucp to be avoided.
 */
checkuser(name)
	register char *name;
{
	char line[BUFSIZ], *strchr();
	FILE *fd;
	int found = 0;

	fd = fopen(FTPUSERS, "r");
	if (fd == NULL)
		return (1);
	while (fgets(line, sizeof (line), fd) != NULL) {
		register char *cp = strchr(line, '\n');

		if (cp)
			*cp = '\0';
		if (strcmp(line, name) == 0) {
			found++;
			break;
		}
	}
	fclose(fd);
	return (!found);
}
 AF_INET;
	data_source.sin_addr = ctrl_addr.sin_addr;
	if (bind(s, &data_source, sizeof (data_source)) < 0)
		goto bad;
/* seteuid(pw->pw_uid); */
	return (fdopen(s, mode));
bad:
/* seteuid(pw->pw_uid); */
unix/servers/ftpd/glob.c                                                                               444     322     145        22752  3621344614  10657                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)glob.c	5.0 (CMC) 09/28/84";
#endif

/*
 * C-shell glob for random programs.
 */

#include <CMC/types.h>
#include <CMC/longnames.h>
#include <CMC/param.h>
#include <sys/stat.h>
#include <CMC/dir.h>

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

#define	QUOTE 0200
#define	TRIM 0177
#define	eq(a,b)		(strcmp(a, b)==0)
#define	GAVSIZ		(NCARGS/6)
#define	isdir(d)	((d.st_mode & S_IFMT) == S_IFDIR)

static	char **gargv;		/* Pointer to the (stack) arglist */
static	short gargc;		/* Number args in gargv */
static	short gnleft;
static	short gflag;
static	int tglob();
char	**glob();
char	*globerr;
char	*home;
struct	passwd *getpwnam();
extern	int errno;
static	char *strspl(), **copyblk(), *strend();
char	*malloc(), *strcpy(), *strcat();

static	int globcnt;

char	*globchars = "`{[*?";

static	char *gpath, *gpathp, *lastgpathp;
static	int globbed;
static	char *entp;
static	char **sortbas;

char **
glob(v)
	register char *v;
{
	char agpath[BUFSIZ];
	char *agargv[GAVSIZ];
	char *vv[2];
	vv[0] = v;
	vv[1] = 0;
	gflag = 0;
	rscan(vv, tglob);
	if (gflag == 0)
		return (copyblk(vv));

	globerr = 0;
	gpath = agpath; gpathp = gpath; *gpathp = 0;
	lastgpathp = &gpath[sizeof agpath - 2];
	ginit(agargv); globcnt = 0;
	collect(v);
	if (globcnt == 0 && (gflag&1)) {
		blkfree(gargv), gargv = 0;
		return (0);
	} else
		return (gargv = copyblk(gargv));
}

static
ginit(agargv)
	char **agargv;
{

	agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
	gnleft = NCARGS - 4;
}

static
collect(as)
	register char *as;
{
	if (eq(as, "{") || eq(as, "{}")) {
		Gcat(as, "");
		sort();
	} else
		acollect(as);
}

static
acollect(as)
	register char *as;
{
	register int ogargc = gargc;

	gpathp = gpath; *gpathp = 0; globbed = 0;
	expand(as);
	if (gargc != ogargc)
		sort();
}

static
sort()
{
	register char **p1, **p2, *c;
	char **Gvp = &gargv[gargc];

	p1 = sortbas;
	while (p1 < Gvp-1) {
		p2 = p1;
		while (++p2 < Gvp)
			if (strcmp(*p1, *p2) > 0)
				c = *p1, *p1 = *p2, *p2 = c;
		p1++;
	}
	sortbas = Gvp;
}

static
expand(as)
	char *as;
{
	register char *cs;
	register char *sgpathp, *oldcs;
	struct stat stb;

	sgpathp = gpathp;
	cs = as;
	if (*cs == '~' && gpathp == gpath) {
		addpath('~');
		for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
			addpath(*cs++);
		if (!*cs || *cs == '/') {
			if (gpathp != gpath + 1) {
				*gpathp = 0;
				if (gethdir(gpath + 1))
					globerr = "Unknown user name after ~";
				strcpy(gpath, gpath + 1);
			} else
				strcpy(gpath, home);
			gpathp = strend(gpath);
		}
	}
	while (!any(*cs, globchars)) {
		if (*cs == 0) {
			if (!globbed)
				Gcat(gpath, "");
			else if (stat(gpath, &stb) >= 0) {
				Gcat(gpath, "");
				globcnt++;
			}
			goto endit;
		}
		addpath(*cs++);
	}
	oldcs = cs;
	while (cs > as && *cs != '/')
		cs--, gpathp--;
	if (*cs == '/')
		cs++, gpathp++;
	*gpathp = 0;
	if (*oldcs == '{') {
		execbrc(cs, ((char *)0));
		return;
	}
	matchdir(cs);
endit:
	gpathp = sgpathp;
	*gpathp = 0;
}

static
matchdir(pattern)
	char *pattern;
{
	struct stat stb;
	register struct direct *dp;
	struct direct *readdir();
	int dirp;
	register int cnt;

	dirp = opendir(gpath);
	if (dirp == NULL) {
		if (globbed)
			return;
		goto patherr2;
	}
	if (fstat(dirp, &stb) < 0)
		goto patherr1;
	if (!isdir(stb)) {
		errno = ENOTDIR;
		goto patherr1;
	}
	while ((dp = readdir(dirp)) != NULL) {
		if (dp->d_ino == 0)
			continue;
		if (match(dp->d_name, pattern)) {
			Gcat(gpath, dp->d_name);
			globcnt++;
		}
	}
	closedir(dirp);
	return;

patherr1:
	closedir(dirp);
patherr2:
	globerr = "Bad directory components";
}

static
execbrc(p, s)
	char *p, *s;
{
	char restbuf[BUFSIZ + 2];
	register char *pe, *pm, *pl;
	int brclev = 0;
	char *lm, savec, *sgpathp;

	for (lm = restbuf; *p != '{'; *lm++ = *p++)
		continue;
	for (pe = ++p; *pe; pe++)
	switch (*pe) {

	case '{':
		brclev++;
		continue;

	case '}':
		if (brclev == 0)
			goto pend;
		brclev--;
		continue;

	case '[':
		for (pe++; *pe && *pe != ']'; pe++)
			continue;
		continue;
	}
pend:
	brclev = 0;
	for (pl = pm = p; pm <= pe; pm++)
	switch (*pm & (QUOTE|TRIM)) {

	case '{':
		brclev++;
		continue;

	case '}':
		if (brclev) {
			brclev--;
			continue;
		}
		goto doit;

	case ','|QUOTE:
	case ',':
		if (brclev)
			continue;
doit:
		savec = *pm;
		* (   (  pm = 0;
		strcpy(lm, pl);
		strcat(restbuf, pe + 1);
		*pm = savec;
		if (s == 0) {
			sgpathp = gpathp;
			expand(restbuf);
			gpathp = sgpathp;
			*gpathp = 0;
		} else if (amatch(s, restbuf))
			return (1);
		sort();
		pl = pm + 1;
		if (brclev)
			return (0);
		continue;

	case '[':
		for (pm++; *pm && *pm != ']'; pm++)
			continue;
		if (!*pm)
			pm--;
		continue;
	}
	if (brclev)
		goto doit;
	return (0);
}

static
match(s, p)
	char *s, *p;
{
	register int c;
	register char *sentp;
	char sglobbed = globbed;

	if (*s == '.' && *p != '.')
		return (0);
	sentp = entp;
	entp = s;
	c = amatch(s, p);
	entp = sentp;
	globbed = sglobbed;
	return (c);
}

static
amatch(s, p)
	register char *s, *p;
{
	register int scc;
	int ok, lc;
	char *sgpathp;
	struct stat stb;
	int c, cc;

	globbed = 1;
	for (;;) {
		scc = *s++ & TRIM;
		switch (c = *p++) {

		case '{':
			return (execbrc(p - 1, s - 1));

		case '[':
			ok = 0;
			lc = 077777;
			while (cc = *p++) {
				if (cc == ']') {
					if (ok)
						break;
					return (0);
				}
				if (cc == '-') {
					if (lc <= scc && scc <= *p++)
						ok++;
				} else
					if (scc == (lc = cc))
						ok++;
			}
			if (cc == 0)
				if (ok)
					p--;
				else
					return 0;
			continue;

		case '*':
			if (!*p)
				return (1);
			if (*p == '/') {
				p++;
				goto slash;
			}
			s--;
			do {
				if (amatch(s, p))
					return (1);
			} while (*s++);
			return (0);

		case 0:
			return (scc == 0);

		default:
			if (c != scc)
				return (0);
			continue;

		case '?':
			if (scc == 0)
				return (0);
			continue;

		case '/':
			if (scc)
				return (0);
slash:
			s = entp;
			sgpathp = gpathp;
			while (*s)
				addpath(*s++);
			addpath('/');
			if (stat(gpath, &stb) == 0 && isdir(stb))
				if (*p == 0) {
					Gcat(gpath, "");
					globcnt++;
				} else
					expand(p);
			gpathp = sgpathp;
			*gpathp = 0;
			return (0);
		}
	}
}

static
Gmatch(s, p)
	register char *s, *p;
{
	register int scc;
	int ok, lc;
	int c, cc;

	for (;;) {
		scc = *s++ & TRIM;
		switch (c = *p++) {

		case '[':
			ok = 0;
			lc = 077777;
			while (cc = *p++) {
				if (cc == ']') {
					if (ok)
						break;
					return (0);
				}
				if (cc == '-') {
					if (lc <= scc && scc <= *p++)
						ok++;
				} else
					if (scc == (lc = cc))
						ok++;
			}
			if (cc == 0)
				if (ok)
					p--;
				else
					return 0;
			continue;

		case '*':
			if (!*p)
				return (1);
			for (s--; *s; s++)
				if (Gmatch(s, p))
					return (1);
			return (0);

		case 0:
			return (scc == 0);

		default:
			if ((c & TRIM) != scc)
				return (0);
			continue;

		case '?':
			if (scc == 0)
				return (0);
			continue;

		}
	}
}

static
Gcat(s1, s2)
	register char *s1, *s2;
{
	register int len = strlen(s1) + strlen(s2) + 1;

	if (len >= gnleft || gargc >= GAVSIZ - 1)
		globerr = "Arguments too long";
	else {
		gargc++;
		gnleft -= len;
		gargv[gargc] = 0;
		gargv[gargc - 1] = strspl(s1, s2);
	}
}

static
addpath(c)
	char c;
{

	if (gpathp >= lastgpathp)
		globerr = "Pathname too long";
	else {
		*gpathp++ = c;
		*gpathp = 0;
	}
}

static
rscan(t, f)
	register char **t;
	int (*f)();
{
	register char *p, c;

	while (p = *t++) {
		if (f == tglob)
			if (*p == '~')
				gflag |= 2;
			else if (eq(p, "{") || eq(p, "{}"))
				continue;
		while (c = *p++)
			(*f)(c);
	}
}

static
scan(t, f)
	register char **t;
	int (*f)();
{
	register char *p, c;

	while (p = *t++)
		while (c = *p)
			*p++ = (*f)(c);
}

static
tglob(c)
	register char c;
{

	if (any(c, globchars))
		gflag |= c == '{' ? 2 : 1;
	return (c);
}

static
trim(c)
	char c;
{

	return (c & TRIM);
}


letter(c)
	register char c;
{

	return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
}

digit(c)
	register char c;
{

	return (c >= '0' && c <= '9');
}

any(c, s)
	register int c;
	register char *s;
{

	while (*s)
		if (*s++ == c)
			return(1);
	return(0);
}
blklen(av)
	register char **av;
{
	register int i = 0;

	while (*av++)
		i++;
	return (i);
}

char **
blkcpy(oav, bv)
	char **oav;
	register char **bv;
{
	register char **av = oav;

	while (*av++ = *bv++)
		continue;
	return (oav);
}

blkfree(av0)
	char **av0;
{
	register char **av = av0;

	while (*av)
		free(*av++);
	free((char *)av0);
}

static
char *
strspl(cp, dp)
	register char *cp, *dp;
{
	register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));

	if (ep == (char *)0)
		fatal("Out of memory");
	strcpy(ep, cp);
	strcat(ep, dp);
	return (ep);
}

static
char **
copyblk(v)
	register char **v;
{
	register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
						sizeof(char **)));
	if (nv == (char **)0)
		fatal("Out of memory");

	return (blkcpy(nv, v));
}

static
char *
strend(cp)
	register char *cp;
{

	while (*cp)
		cp++;
	return (cp);
}
/*
 * Extract a home directory from the password file
 * The argument points to a buffer where the name of the
 * user whose home directory is sought is currently.
 * We write the home directory of the user back there.
 */
gethdir(home)
	char *home;
{
	register struct passwd *pp = getpwnam(home);

	if (pp == 0)
		return (1);
	strcpy(home, pp->pw_dir);
	return (0);
}
teuid(pw->pw_uid); */
unix/servers/ftpd/interface.c                                                                          444     322     145         3364  3621344615  11653                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

static char sccsid[] = "@(#)interface.c	1.0 (CMC) 12/5/84";

# include <CMC/errno.h>
# include <pwd.h>

/*
 * Simulate the 4.2 mkdir, rmdir, and rename system calls.
 */

mkdir (path, mode)
char *path;
int mode;
{
	return (directory ("/bin/mkdir", "mkdir", path, 0, 0));
}

rmdir (path)
char *path;
{
	return (directory ("/bin/rmdir", "rmdir", path, 0, 0));
}

rename (from, to)
char *from, *to;
{
	return (directory ("/bin/mv", "mv", from, to, 0));
}

static
directory (path, p1, p2, p3, p4)
char *path, *p1, *p2, *p3, *p4;
{
	extern int errno;
	extern	struct	passwd *pw;
	int status;
	int pid;

	errno = 0;

	if ((pid = fork ()) == -1)
		return (-1);
	if (pid == 0)
	{
		setuid (pw->pw_uid);
		close (0);
		close (1);
		execl (path, p1, p2, p3, p4, 0);
		exit (-1);
	}
	if (wait (&status) != pid || status != 0)
		return (-1);
	return (0);
}

static char ppath[257];

char *
parent ( path )
char *path;
{
	char *strrchr();

	strcpy ( ppath, "../" );
	strncat ( ppath, path, sizeof ( ppath ) -4 );
	*strrchr ( ppath, '/' ) = 0;
	return ( ppath );
}

accessible ( path, mode )
char *path;
{
	extern int errno;
	extern	struct	passwd *pw;
	register int pid;
	int	status;

	if ( (pid = fork()) == -1 )
		return ( -1 );

	if ( pid == 0 ) {	/* child does the work */
		setuid ( pw->pw_uid );
		exit ( access (path,mode) == 0 ? 0 : errno );
	}

	if ( wait ( &status ) == pid ) {
		errno = (status>>8) & 0xFF;
		return ( status == 0 );
	}
	else {
		errno = EACCES;
		return ( 0 );
	}
}
				globcnt++;
				} else
					expand(p);
			gpathp = sgpathp;
			*gpathp = 0;
			return (0);
		}
	}
}

static
Gmatch(s, p)
	register char *s, *p;
{
	register int scc;
	int ok, lc;
	int c, cc;

	for (;;) {
		scc = *s++ & TRIM;
		switch (c = *p++) {

		case '[':
			ok unix/servers/ftpd/vers.c                                                                               444     322     145          520  3621344615  10641                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

char version[] = "CMC Unix Sys V";
ce.c	1.0 (CMC) 12/5/84";

# include <CMC/errno.h>
# include <pwd.h>

/*
 * Simulate the 4.2 mkdir, rmdir, and rename system calls.
 */

mkdir (path, mode)
char *path;
int mode;unix/servers/ftpd/README                                                                               444     322     145          260  3621344616  10400                                                                                                                                                                                                                                                                                                                                                                      	This directory contains the source for the ftp daemon process.
The file y.tab.c is the yacc output created from ftpcmd.y; it is included
for those systems with broken yacc's.
ion, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

char version[] = "CMC Unix Sys V";
ce.c	1.0 (CMC) 12/5/84";

# include <CMC/errno.h>
# include <pwd.h>

/*
 * Simulate the 4.2 mkdir, rmdir, and rename system calls.
 */

mkdir (path, mode)
char *path;
int mode;unix/servers/ftpd/y.tab.c                                                                              444     322     145       100435  3621344617  10767                                                                                                                                                                                                                                                                                                                                                                       (   (  
# line 18 "ftpcmd.y"

#ifndef lint
static char sccsid[] = "@(#)ftpcmd.y	5.0 (CMC) 09/28/84";
#endif

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>

#include <CMC/in.h>

#include <CMC/ftp.h>

#include <stdio.h>
#include <signal.h>
#include <ctype.h>
#include <pwd.h>
#include <setjmp.h>

extern	struct sockaddr_in data_dest;
extern	int logged_in;
extern	struct passwd *pw;
extern	int guest;
extern	int logging;
extern	int type;
extern	int form;
extern	int debug;
extern	int timeout;
extern	char hostname[];
extern	char *globerr;
extern	int usedefault;
char	**glob();

static	int cmd_type;
static	int cmd_form;
static	int cmd_bytesz;

char	*strchr();
# define A 257
# define B 258
# define C 259
# define E 260
# define F 261
# define I 262
# define L 263
# define N 264
# define P 265
# define R 266
# define S 267
# define T 268
# define SP 269
# define CRLF 270
# define COMMA 271
# define STRING 272
# define NUMBER 273
# define USER 274
# define PASS 275
# define ACCT 276
# define REIN 277
# define QUIT 278
# define PORT 279
# define PASV 280
# define TYPE 281
# define STRU 282
# define MODE 283
# define RETR 284
# define STOR 285
# define APPE 286
# define MLFL 287
# define MAIL 288
# define MSND 289
# define MSOM 290
# define MSAM 291
# define MRSQ 292
# define MRCP 293
# define ALLO 294
# define REST 295
# define RNFR 296
# define RNTO 297
# define ABOR 298
# define DELE 299
# define CWD 300
# define LIST 301
# define NLST 302
# define SITE 303
# define STAT 304
# define HELP 305
# define NOOP 306
# define XMKD 307
# define XRMD 308
# define XPWD 309
# define XCUP 310
# define LEXERR 311
#define yyclearin yychar = -1
#define yyerrok yyerrflag = 0
extern int yychar;
extern int yyerrflag;
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 150
#endif
#ifndef YYSTYPE
#define YYSTYPE int
#endif
YYSTYPE yylval, yyval;
typedef int yytabelem;
# define YYERRCODE 256

# line 448 "ftpcmd.y"


extern jmp_buf errcatch;

#define	CMD	0	/* beginning of command */
#define	ARGS	1	/* expect miscellaneous arguments */
#define	STR1	2	/* expect SP followed by STRING */
#define	STR2	3	/* expect STRING */
#define	OSTR	4	/* optional STRING */

struct tab {
	char	*name;
	short	token;
	short	state;
	short	implemented;	/* 1 if command is implemented */
	char	*help;
};

struct tab cmdtab[] = {		/* In order defined in RFC 765 */
	{ "USER", USER, STR1, 1,	"<sp> username" },
	{ "PASS", PASS, STR1, 1,	"<sp> password" },
	{ "ACCT", ACCT, STR1, 0,	"(specify account)" },
	{ "REIN", REIN, ARGS, 0,	"(reinitialize server state)" },
	{ "QUIT", QUIT, ARGS, 1,	"(terminate service)", },
	{ "PORT", PORT, ARGS, 1,	"<sp> b0, b1, b2, b3, b4" },
	{ "PASV", PASV, ARGS, 0,	"(set server in passive mode)" },
	{ "TYPE", TYPE, ARGS, 1,	"<sp> [ A | E | I | L ]" },
	{ "STRU", STRU, ARGS, 1,	"(specify file structure)" },
	{ "MODE", MODE, ARGS, 1,	"(specify transfer mode)" },
	{ "RETR", RETR, STR1, 1,	"<sp> file-name" },
	{ "STOR", STOR, STR1, 1,	"<sp> file-name" },
	{ "APPE", APPE, STR1, 1,	"<sp> file-name" },
	{ "MLFL", MLFL, OSTR, 0,	"(mail file)" },
	{ "MAIL", MAIL, OSTR, 0,	"(mail to user)" },
	{ "MSND", MSND, OSTR, 0,	"(mail send to terminal)" },
	{ "MSOM", MSOM, OSTR, 0,	"(mail send to terminal or mailbox)" },
	{ "MSAM", MSAM, OSTR, 0,	"(mail send to terminal and mailbox)" },
	{ "MRSQ", MRSQ, OSTR, 0,	"(mail recipient scheme question)" },
	{ "MRCP", MRCP, STR1, 0,	"(mail recipient)" },
	{ "ALLO", ALLO, ARGS, 1,	"allocate storage (vacuously)" },
	{ "REST", REST, STR1, 0,	"(restart command)" },
	{ "RNFR", RNFR, STR1, 1,	"<sp> file-name" },
	{ "RNTO", RNTO, STR1, 1,	"<sp> file-name" },
	{ "ABOR", ABOR, ARGS, 0,	"(abort operation)" },
	{ "DELE", DELE, STR1, 1,	"<sp> file-name" },
	{ "CWD",  CWD,  OSTR, 1,	"[ <sp> directory-name]" },
	{ "XCWD", CWD,	OSTR, 1,	"[ <sp> directory-name ]" },
	{ "LIST", LIST, OSTR, 1,	"[ <sp> path-name ]" },
	{ "NLST", NLST, OSTR, 1,	"[ <sp> path-name ]" },
	{ "SITE", SITE, STR1, 0,	"(get site parameters)" },
	{ "STAT", STAT, OSTR, 0,	"(get server status)" },
	{ "HELP", HELP, OSTR, 1,	"[ <sp> <string> ]" },
	{ "NOOP", NOOP, ARGS, 1,	"" },
	{ "XMKD", XMKD, STR1, 1,	"<sp> path-name" },
	{ "XRMD", XRMD, STR1, 1,	"<sp> path-name" },
	{ "XPWD", XPWD, ARGS, 1,	"return current directory" },
	{ "XCUP", XCUP, ARGS, 1,	"change to parent directory" },
	{ NULL,   0,    0,    0,	0 }
};

struct tab *
lookup(cmd)
	char *cmd;
{
	register struct tab *p;

	for (p = cmdtab; p->name != NULL; p++)
		if (strcmp(cmd, p->name) == 0)
			return (p);
	return (0);
}

#include <CMC/telnet.h>

/*
 * getline - a hacked up version of fgets to ignore TELNET escape codes.
 */
char *
getline(s, n, iop)
	char *s;
	register FILE *iop;
{
	register c;
	register char *cs;

	cs = s;
	while (--n > 0 && (c = getc(iop)) >= 0) {
		while (c == IAC) {
			c = getc(iop);	/* skip command */
			c = getc(iop);	/* try next char */
		}
		*cs++ = c;
		if (c=='\n')
			break;
	}
	if (c < 0 && cs == s)
		return (NULL);
	*cs++ = '\0';
	if (debug) {
		fprintf(stderr, "FTPD: command: %s", s);
		if (c != '\n')
			putc('\n', stderr);
		fflush(stderr);
	}
	return (s);
}

static int
toolong()
{
	long now;
	extern char *ctime();

	reply(421,
	  "Timeout (%d seconds): closing control connection.", timeout);
	time(&now);
	if (logging) {
		fprintf(stderr,
			"FTPD: User %s timed out after %d seconds at %s",
			(pw ? pw -> pw_name : "unknown"), timeout, ctime(&now));
		fflush(stderr);
	}
	dologout(1);
}

yylex()
{
	static char cbuf[512];
	static int cpos, state;
	register char *cp;
	register struct tab *p;
	int n;
	char c;

	for (;;) {
		switch (state) {

		case CMD:
			signal(SIGALRM, toolong);
			alarm(timeout);
			if (getline(cbuf, sizeof(cbuf)-1, stdin) == NULL) {
				reply(221, "You could at least say goodbye.");
				dologout(0);
			}
			alarm(0);
			if (strchr(cbuf, '\r')) {
				cp = strchr(cbuf, '\r');
				cp[0] = '\n'; cp[1] = 0;
			}
			if (strchr(cbuf, ' '))
				cpos = strchr(cbuf, ' ') - cbuf;
			else
				cpos = 4;
			c = cbuf[cpos];
			cbuf[cpos] = '\0';
			upper(cbuf);
			p = lookup(cbuf);
			cbuf[cpos] = c;
			if (p != 0) {
				if (p->implemented == 0) {
					nack(p->name);
					longjmp(errcatch);
					/* NOTREACHED */
				}
				state = p->state;
				yylval = (int) p->name;
				return (p->token);
			}
			break;

		case OSTR:
			if (cbuf[cpos] == '\n') {
				state = CMD;
				return (CRLF);
			}
			/* FALL THRU */

		case STR1:
			if (cbuf[cpos] == ' ') {
				cpos++;
				state = STR2;
				return (SP);
			}
			break;

		case STR2:
			cp = &cbuf[cpos];
			n = strlen(cp);
			cpos += n - 1;
			/*
			 * Make sure the string is nonempty and \n terminated.
			 */
			if (n > 1 && cbuf[cpos] == '\n') {
				cbuf[cpos] = '\0';
				yylval = copy(cp);
				cbuf[cpos] = '\n';
				state = ARGS;
				return (STRING);
			}
			break;

		case ARGS:
			if (isdigit(cbuf[cpos])) {
				cp = &cbuf[cpos];
				while (isdigit(cbuf[++cpos]))
					;
				c = cbuf[cpos];
				cbuf[cpos] = '\0';
				yylval = atoi(cp);
				cbuf[cpos] = c;
				return (NUMBER);
			}
			switch (cbuf[cpos++]) {

			case '\n':
				state = CMD;
				return (CRLF);

			case ' ':
				return (SP);

			case ',':
				return (COMMA);

			case 'A':
			case 'a':
				return (A);

			case 'B':
			case 'b':
				return (B);

			case 'C':
			case 'c':
				return (C);

			case 'E':
			case 'e':
				return (E);

			case 'F':
			case 'f':
				return (F);

			case 'I':
			case 'i':
				return (I);

			case 'L':
			case 'l':
				return (L);

			case 'N':
			case 'n':
				return (N);

			case 'P':
			case 'p':
				return (P);

			case 'R':
			case 'r':
				return (R);

			case 'S':
			case 's':
				return (S);

			case 'T':
			case 't':
				return (T);

			}
			break;

		default:
			fatal("Unknown state in scanner.");
		}
		yyerror();
		state = CMD;
		longjmp(errcatch);
	}
}

upper(s)
	char *s;
{
	while (*s != '\0') {
		if (islower(*s))
			*s = toupper(*s);
		s++;
	}
}

copy(s)
	char *s;
{
	char *p;
	extern char *malloc();

	p = malloc(strlen(s) + 1);
	if (p == NULL)
		fatal("Ran out of memory.");
	strcpy(p, s);
	return ((int)p);
}

help(s)
	char *s;
{
	register struct tab *c;
	register int width, NCMDS;

	width = 0, NCMDS = 0;
	for (c = cmdtab; c->name != NULL; c++) {
		int len = strlen(c->name);

		if (c->implemented == 0)
			len++;
		if (len > width)
			width = len;
		NCMDS++;
	}
	width = (width + 8) &~ 7;
	if (s == 0) {
		register int i, j, w;
		int columns, lines;

		lreply(214,
	  "The following commands are recognized (* =>'s unimplemented).");
		columns = 76 / width;
		if (columns == 0)
			columns = 1;
		lines = (NCMDS + columns - 1) / columns;
		for (i = 0; i < lines; i++) {
			printf("    ");
			for (j = 0; j < columns; j++) {
				c = cmdtab + j * lines + i;
				printf("%s%c", c->name,
					c->implemented ? ' ' : '*');
				if (c + lines >= &cmdtab[NCMDS])
					break;
				w = strlen(c->name);
				while (w < width) {
					putchar(' ');
					w++;
				}
			}
			printf("\r\n");
		}
		fflush(stdout);
		reply(214, "Direct comments to ftp-bugs@%s.", hostname);
		return;
	}
	upper(s);
	c = lookup(s);
	if (c == (struct tab *)0) {
		reply(504, "Unknown command %s.", s);
		return;
	}
	if (c->implemented)
		reply(214, "Syntax: %s %s", c->name, c->help);
	else
		reply(214, "%-*s\t%s; unimplemented.", width, c->name, c->help);
}
yytabelem yyexca[] ={
-1, 1,
	0, -1,
	-2, 0,
	};
# define YYNPROD 57
# define YYLAST 205
yytabelem yyact[]={

    25,    52,    98,   143,   141,   139,   100,   137,   100,   118,
    73,    59,   106,    84,    57,    55,   142,   140,     3,     4,
   138,   136,    24,     5,    94,     6,     7,     8,    10,    11,
    12,    83,    82,    80,    79,    78,    77,   135,     9,   134,
    27,    43,    42,    15,    16,    14,    13,   133,   132,    18,
    19,    20,    21,    22,    23,   131,   130,   129,   128,   127,
   126,   125,   122,   113,   103,   102,   101,   120,    95,    93,
    92,   121,    91,   104,    88,    87,    50,    49,    44,    97,
    96,    90,    89,    86,    85,    81,    76,    75,    74,    71,
    72,    34,    33,    32,    31,    30,    29,    28,    70,    66,
    99,    35,    61,    68,    67,    62,   119,    63,    64,    51,
    26,   105,    17,    36,    37,    38,    39,    40,    41,    69,
    65,    60,    45,    46,    (   (   47,    48,    58,    56,    54,    53,
     2,     1,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,   107,
   108,     0,   109,     0,   110,   111,     0,   112,     0,   114,
   115,     0,     0,   116,   117,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,   124,
     0,     0,     0,     0,   123 };
yytabelem yypact[]={

 -1000,  -256, -1000,  -172,  -173,  -174,  -175,  -176,  -177,  -178,
 -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,  -228,  -192,
 -1000, -1000, -1000, -1000,  -193,  -194,  -296, -1000,  -257,  -258,
  -262,  -155,  -162,  -169,  -263,  -181,  -182,  -183,  -234,  -236,
  -184,  -238, -1000,  -259, -1000,  -185,  -186,  -195,  -196, -1000,
 -1000, -1000,  -187,  -188,  -198, -1000,  -200, -1000,  -201,  -247,
  -202,  -189,  -190, -1000,  -267,  -204, -1000, -1000, -1000,  -205,
 -1000, -1000, -1000,  -206,  -260,  -260,  -260, -1000,  -260, -1000,
  -260,  -260, -1000,  -260,  -207,  -260,  -260, -1000, -1000,  -260,
  -260, -1000, -1000, -1000,  -264, -1000,  -197,  -197,  -265, -1000,
 -1000, -1000, -1000, -1000,  -209, -1000, -1000,  -210,  -211,  -212,
  -213,  -214,  -215, -1000,  -222,  -223,  -231,  -233,  -250, -1000,
 -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000,
 -1000, -1000, -1000, -1000, -1000, -1000,  -266,  -251,  -268,  -254,
  -269,  -255,  -270, -1000 };
yytabelem yypgo[]={

     0,   131,   130,   128,   127,   126,   121,   120,   119,   101,
    73,   112,   100,   106,   111,   110,   109 };
yytabelem yyr1[]={

     0,     1,     1,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
     3,     4,    12,     5,    13,    13,    13,     6,     6,     6,
     6,     6,     6,     6,     6,     7,     7,     7,     8,     8,
     8,    10,    14,    11,    15,    16,     9 };
yytabelem yyr2[]={

     0,     0,     4,     9,     9,     9,     9,     9,     9,     9,
    11,    11,    11,     7,    11,     7,    11,    11,     7,    11,
     2,     5,     9,     5,    11,    11,     7,     7,     5,     5,
     2,     2,     2,    23,     3,     3,     3,     3,     7,     3,
     7,     3,     3,     7,     5,     3,     3,     3,     3,     3,
     3,     3,     2,     5,    11,     9,     1 };
yytabelem yychk[]={

 -1000,    -1,    -2,   274,   275,   279,   281,   282,   283,   294,
   284,   285,   286,   302,   301,   299,   300,   -11,   305,   306,
   307,   308,   309,   310,   278,   256,   -15,   296,   269,   269,
   269,   269,   269,   269,   269,    -9,    -9,    -9,    -9,    -9,
    -9,    -9,   270,   269,   270,    -9,    -9,    -9,    -9,   270,
   270,   -16,   297,    -9,    -3,   272,    -4,   272,    -5,   273,
    -6,   257,   260,   262,   263,    -7,   261,   266,   265,    -8,
   267,   258,   259,   273,   269,   269,   269,   270,   269,   270,
   269,   269,   270,   269,   272,   269,   269,   270,   270,   269,
   269,   270,   270,   270,   271,   270,   269,   269,   269,   -12,
   273,   270,   270,   270,   -10,   -14,   272,   -10,   -10,   -10,
   -10,   -10,   -10,   270,   -10,   -10,   -10,   -10,   273,   -13,
   264,   268,   259,   -13,   -12,   270,   270,   270,   270,   270,
   270,   270,   270,   270,   270,   270,   271,   273,   271,   273,
   271,   273,   271,   273 };
yytabelem yydef[]={

     1,    -2,     2,     0,     0,     0,     0,     0,     0,     0,
    56,    56,    56,    56,    56,    56,    56,    20,     0,     0,
    56,    56,    56,    56,     0,     0,     0,    56,     0,     0,
     0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
     0,     0,    21,     0,    23,     0,     0,     0,     0,    28,
    29,    53,     0,     0,     0,    30,     0,    31,     0,     0,
     0,    37,    39,    41,    42,     0,    45,    46,    47,     0,
    48,    49,    50,     0,     0,     0,     0,    13,     0,    15,
     0,     0,    18,     0,     0,     0,     0,    26,    27,     0,
     0,     3,     4,     5,     0,     6,     0,     0,     0,    44,
    32,     7,     8,     9,     0,    51,    52,     0,     0,     0,
     0,     0,     0,    22,     0,     0,     0,     0,     0,    38,
    34,    35,    36,    40,    43,    10,    11,    12,    14,    16,
    17,    19,    24,    25,    55,    54,     0,     0,     0,     0,
     0,     0,     0,    33 };
typedef struct { char *t_name; int t_val; } yytoktype;
#ifndef YYDEBUG
#	define YYDEBUG	0	/* don't allow debugging */
#endif

#if YYDEBUG

yytoktype yytoks[] =
{
	"A",	257,
	"B",	258,
	"C",	259,
	"E",	260,
	"F",	261,
	"I",	262,
	"L",	263,
	"N",	264,
	"P",	265,
	"R",	266,
	"S",	267,
	"T",	268,
	"SP",	269,
	"CRLF",	270,
	"COMMA",	271,
	"STRING",	272,
	"NUMBER",	273,
	"USER",	274,
	"PASS",	275,
	"ACCT",	276,
	"REIN",	277,
	"QUIT",	278,
	"PORT",	279,
	"PASV",	280,
	"TYPE",	281,
	"STRU",	282,
	"MODE",	283,
	"RETR",	284,
	"STOR",	285,
	"APPE",	286,
	"MLFL",	287,
	"MAIL",	288,
	"MSND",	289,
	"MSOM",	290,
	"MSAM",	291,
	"MRSQ",	292,
	"MRCP",	293,
	"ALLO",	294,
	"REST",	295,
	"RNFR",	296,
	"RNTO",	297,
	"ABOR",	298,
	"DELE",	299,
	"CWD",	300,
	"LIST",	301,
	"NLST",	302,
	"SITE",	303,
	"STAT",	304,
	"HELP",	305,
	"NOOP",	306,
	"XMKD",	307,
	"XRMD",	308,
	"XPWD",	309,
	"XCUP",	310,
	"LEXERR",	311,
	"-unknown-",	-1	/* ends search */
};

char * yyreds[] =
{
	"-no such reduction-",
	"cmd_list : /* empty */",
	"cmd_list : cmd_list cmd",
	"cmd : USER SP username CRLF",
	"cmd : PASS SP password CRLF",
	"cmd : PORT SP host_port CRLF",
	"cmd : TYPE SP type_code CRLF",
	"cmd : STRU SP struct_code CRLF",
	"cmd : MODE SP mode_code CRLF",
	"cmd : ALLO SP NUMBER CRLF",
	"cmd : RETR check_login SP pathname CRLF",
	"cmd : STOR check_login SP pathname CRLF",
	"cmd : APPE check_login SP pathname CRLF",
	"cmd : NLST check_login CRLF",
	"cmd : NLST check_login SP pathname CRLF",
	"cmd : LIST check_login CRLF",
	"cmd : LIST check_login SP pathname CRLF",
	"cmd : DELE check_login SP pathname CRLF",
	"cmd : CWD check_login CRLF",
	"cmd : CWD check_login SP pathname CRLF",
	"cmd : rename_cmd",
	"cmd : HELP CRLF",
	"cmd : HELP SP STRING CRLF",
	"cmd : NOOP CRLF",
	"cmd : XMKD check_login SP pathname CRLF",
	"cmd : XRMD check_login SP pathname CRLF",
	"cmd : XPWD check_login CRLF",
	"cmd : XCUP check_login CRLF",
	"cmd : QUIT CRLF",
	"cmd : error CRLF",
	"username : STRING",
	"password : STRING",
	"byte_size : NUMBER",
	"host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER",
	"form_code : N",
	"form_code : T",
	"form_code : C",
	"type_code : A",
	"type_code : A SP form_code",
	"type_code : E",
	"type_code : E SP form_code",
	"type_code : I",
	"type_code : L",
	"type_code : L SP byte_size",
	"type_code : L byte_size",
	"struct_code : F",
	"struct_code : R",
	"struct_code : P",
	"mode_code : S",
	"mode_code : B",
	"mode_code : C",
	"pathname : pathstring",
	"pathstring : STRING",
	"rename_cmd : rename_from rename_to",
	"rename_from : RNFR check_login SP pathname CRLF",
	"rename_to : RNTO SP pathname CRLF",
	"check_login : /* empty */",
};
#endif /* YYDEBUG */
/*	@(#)yaccpar	1.9	*/

/*
** Skeleton parser driver for yacc output
*/

/*
** yacc user known macros and defines
*/
#define YYERROR		goto yyerrlab
#define YYACCEPT	return(0)
#define YYABORT		return(1)
#define YYBACKUP( newtoken, newvalue )\
{\
	if ( yychar >= 0 || ( yyr2[ yytmp ] >> 1 ) != 1 )\
	{\
		yyerror( "syntax error - cannot backup" );\
		goto yyerrlab;\
	}\
	yychar = newtoken;\
	yystate = *yyps;\
	yylval = newvalue;\
	goto yynewstate;\
}
#define YYRECOVERING()	(!!yyerrflag)
#ifndef YYDEBUG
#	define YYDEBUG	1	/* make debugging available */
#endif

/*
** user known globals
*/
int yydebug;			/* set to 1 to get debugging */

/*
** driver internal defines
*/
#define YYFLAG		(-1000)

/*
** global variables used by the parser
*/
YYSTYPE yyv[ YYMAXDEPTH ];	/* value stack */
int yys[ YYMAXDEPTH ];		/* state stack */

YYSTYPE *yypv;			/* top of value stack */
int *yyps;			/* top of state stack */

int yystate;			/* current state */
int yytmp;			/* extra var (lasts between blocks) */

int yynerrs;			/* number of errors */
int yyerrflag;			/* error recovery flag */
int yychar;			/* current input token number */



/*
** yyparse - return 0 if worked, 1 if syntax error not recovered from
*/
int
yyparse()
{
	register YYSTYPE *yypvt;	/* top of value stack for $vars */

	/*
	** Initialize externals - yyparse may be called more than once
	*/
	yypv = &yyv[-1];
	yyps = &yys[-1];
	yystate = 0;
	yytmp = 0;
	yynerrs = 0;
	yyerrflag = 0;
	yychar = -1;

	goto yystack;
	{
		register YYSTYPE *yy_pv;	/* top of value stack */
		register int *yy_ps;		/* top of state stack */
		register int yy_state;		/* current state */
		register int  yy_n;		/* internal state number info */

		/*
		** get globals into registers.
		** branch to here only if YYBACKUP was called.
		*/
	yynewstate:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;
		goto yy_newstate;

		/*
		** get globals into registers.
		** either we just started, or we just finished a reduction
		*/
	yystack:
		yy_pv = yypv;
		yy_ps = yyps;
		yy_state = yystate;

		/*
		** top of for (;;) loop while no reductions done
		*/
	yy_stack:
		/*
		** put a state and value onto the stacks
		*/
#if YYDEBUG
		/*
		** if debugging, look up token value in list of value vs.
		** name pairs.  0 and negative (-1) are special values.
		** Note: linear search is used since time is not a real
		** consideration while debugging.
		*/
		if ( yydebug )
		{
			register int yy_i;

			printf( "State %d, token ", yy_state );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ++yy_ps >= &yys[ YYMAXDEPT (   (  H ] )	/* room on stack? */
		{
			yyerror( "yacc stack overflow" );
			YYABORT;
		}
		*yy_ps = yy_state;
		*++yy_pv = yyval;

		/*
		** we have a new state - find out what to do
		*/
	yy_newstate:
		if ( ( yy_n = yypact[ yy_state ] ) <= YYFLAG )
			goto yydefault;		/* simple state */
#if YYDEBUG
		/*
		** if debugging, need to mark whether new token grabbed
		*/
		yytmp = yychar < 0;
#endif
		if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
			yychar = 0;		/* reached EOF */
#if YYDEBUG
		if ( yydebug && yytmp )
		{
			register int yy_i;

			printf( "Received token " );
			if ( yychar == 0 )
				printf( "end-of-file\n" );
			else if ( yychar < 0 )
				printf( "-none-\n" );
			else
			{
				for ( yy_i = 0; yytoks[yy_i].t_val >= 0;
					yy_i++ )
				{
					if ( yytoks[yy_i].t_val == yychar )
						break;
				}
				printf( "%s\n", yytoks[yy_i].t_name );
			}
		}
#endif /* YYDEBUG */
		if ( ( ( yy_n += yychar ) < 0 ) || ( yy_n >= YYLAST ) )
			goto yydefault;
		if ( yychk[ yy_n = yyact[ yy_n ] ] == yychar )	/*valid shift*/
		{
			yychar = -1;
			yyval = yylval;
			yy_state = yy_n;
			if ( yyerrflag > 0 )
				yyerrflag--;
			goto yy_stack;
		}

	yydefault:
		if ( ( yy_n = yydef[ yy_state ] ) == -2 )
		{
#if YYDEBUG
			yytmp = yychar < 0;
#endif
			if ( ( yychar < 0 ) && ( ( yychar = yylex() ) < 0 ) )
				yychar = 0;		/* reached EOF */
#if YYDEBUG
			if ( yydebug && yytmp )
			{
				register int yy_i;

				printf( "Received token " );
				if ( yychar == 0 )
					printf( "end-of-file\n" );
				else if ( yychar < 0 )
					printf( "-none-\n" );
				else
				{
					for ( yy_i = 0;
						yytoks[yy_i].t_val >= 0;
						yy_i++ )
					{
						if ( yytoks[yy_i].t_val
							== yychar )
						{
							break;
						}
					}
					printf( "%s\n", yytoks[yy_i].t_name );
				}
			}
#endif /* YYDEBUG */
			/*
			** look through exception table
			*/
			{
				register int *yyxi = yyexca;

				while ( ( *yyxi != -1 ) ||
					( yyxi[1] != yy_state ) )
				{
					yyxi += 2;
				}
				while ( ( *(yyxi += 2) >= 0 ) &&
					( *yyxi != yychar ) )
					;
				if ( ( yy_n = yyxi[1] ) < 0 )
					YYACCEPT;
			}
		}

		/*
		** check for syntax error
		*/
		if ( yy_n == 0 )	/* have an error */
		{
			/* no worry about speed here! */
			switch ( yyerrflag )
			{
			case 0:		/* new error */
				yyerror( "syntax error" );
				goto skip_init;
			yyerrlab:
				/*
				** get globals into registers.
				** we have a user generated syntax type error
				*/
				yy_pv = yypv;
				yy_ps = yyps;
				yy_state = yystate;
				yynerrs++;
			skip_init:
			case 1:
			case 2:		/* incompletely recovered error */
					/* try again... */
				yyerrflag = 3;
				/*
				** find state where "error" is a legal
				** shift action
				*/
				while ( yy_ps >= yys )
				{
					yy_n = yypact[ *yy_ps ] + YYERRCODE;
					if ( yy_n >= 0 && yy_n < YYLAST &&
						yychk[yyact[yy_n]] == YYERRCODE)					{
						/*
						** simulate shift of "error"
						*/
						yy_state = yyact[ yy_n ];
						goto yy_stack;
					}
					/*
					** current state has no shift on
					** "error", pop stack
					*/
#if YYDEBUG
#	define _POP_ "Error recovery pops state %d, uncovers state %d\n"
					if ( yydebug )
						printf( _POP_, *yy_ps,
							yy_ps[-1] );
#	undef _POP_
#endif
					yy_ps--;
					yy_pv--;
				}
				/*
				** there is no state on stack with "error" as
				** a valid shift.  give up.
				*/
				YYABORT;
			case 3:		/* no shift yet; eat a token */
#if YYDEBUG
				/*
				** if debugging, look up token in list of
				** pairs.  0 and negative shouldn't occur,
				** but since timing doesn't matter when
				** debugging, it doesn't hurt to leave the
				** tests here.
				*/
				if ( yydebug )
				{
					register int yy_i;

					printf( "Error recovery discards " );
					if ( yychar == 0 )
						printf( "token end-of-file\n" );
					else if ( yychar < 0 )
						printf( "token -none-\n" );
					else
					{
						for ( yy_i = 0;
							yytoks[yy_i].t_val >= 0;
							yy_i++ )
						{
							if ( yytoks[yy_i].t_val
								== yychar )
							{
								break;
							}
						}
						printf( "token %s\n",
							yytoks[yy_i].t_name );
					}
				}
#endif /* YYDEBUG */
				if ( yychar == 0 )	/* reached EOF. quit */
					YYABORT;
				yychar = -1;
				goto yy_newstate;
			}
		}/* end if ( yy_n == 0 ) */
		/*
		** reduction by production yy_n
		** put stack tops, etc. so things right after switch
		*/
#if YYDEBUG
		/*
		** if debugging, print the string that is the user's
		** specification of the reduction which is just about
		** to be done.
		*/
		if ( yydebug )
			printf( "Reduce by (%d) \"%s\"\n",
				yy_n, yyreds[ yy_n ] );
#endif
		yytmp = yy_n;			/* value to switch over */
		yypvt = yy_pv;			/* $vars top of value stack */
		/*
		** Look in goto table for next state
		** Sorry about using yy_state here as temporary
		** register variable, but why not, if it works...
		** If yyr2[ yy_n ] doesn't have the low order bit
		** set, then there is no action to be done for
		** this reduction.  So, no saving & unsaving of
		** registers done.  The only difference between the
		** code just after the if and the body of the if is
		** the goto yy_stack in the body.  This way the test
		** can be made before the choice of what to do is needed.
		*/
		{
			/* length of production doubled with extra bit */
			register int yy_len = yyr2[ yy_n ];

			if ( !( yy_len & 01 ) )
			{
				yy_len >>= 1;
				yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
				yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
					*( yy_ps -= yy_len ) + 1;
				if ( yy_state >= YYLAST ||
					yychk[ yy_state =
					yyact[ yy_state ] ] != -yy_n )
				{
					yy_state = yyact[ yypgo[ yy_n ] ];
				}
				goto yy_stack;
			}
			yy_len >>= 1;
			yyval = ( yy_pv -= yy_len )[1];	/* $$ = $1 */
			yy_state = yypgo[ yy_n = yyr1[ yy_n ] ] +
				*( yy_ps -= yy_len ) + 1;
			if ( yy_state >= YYLAST ||
				yychk[ yy_state = yyact[ yy_state ] ] != -yy_n )
			{
				yy_state = yyact[ yypgo[ yy_n ] ];
			}
		}
					/* save until reenter driver code */
		yystate = yy_state;
		yyps = yy_ps;
		yypv = yy_pv;
	}
	/*
	** code supplied by user is placed in this switch
	*/
	switch( yytmp )
	{
		
case 3:
# line 83 "ftpcmd.y"
 {
			extern struct passwd *getpwnam();

			if (strcmp(yypvt[-1], "ftp") == 0 ||
			  strcmp(yypvt[-1], "anonymous") == 0) {
				if ((pw = getpwnam("ftp")) != NULL) {
					guest = 1;
					reply(331,
				  "Guest login ok, send ident as password.");
				}
			} else if (checkuser(yypvt[-1])) {
				guest = 0;
				pw = getpwnam(yypvt[-1]);
				reply(331, "Password required for %s.", yypvt[-1]);
			}
			if (pw == NULL)
				reply(530, "User %s unknown.", yypvt[-1]);
			free(yypvt[-1]);
		} break;
case 4:
# line 103 "ftpcmd.y"
 {
			pass(yypvt[-1]);
			free(yypvt[-1]);
		} break;
case 5:
# line 108 "ftpcmd.y"
 {
			usedefault = 0;
			ack(yypvt[-3]);
		} break;
case 6:
# line 113 "ftpcmd.y"
 {
			switch (cmd_type) {

			case TYPE_A:
				if (cmd_form == FORM_N) {
					reply(200, "Type set to A.");
					type = cmd_type;
					form = cmd_form;
				} else
					reply(504, "Form must be N.");
				break;

			case TYPE_E:
				reply(504, "Type E not implemented.");
				break;

			case TYPE_I:
				reply(200, "Type set to I.");
				type = cmd_type;
				break;

			case TYPE_L:
				if (cmd_bytesz == 8) {
					reply(200,
					    "Type set to L (byte size 8).");
					type = cmd_type;
				} else
					reply(504, "Byte size must be 8.");
			}
		} break;
case 7:
# line 144 "ftpcmd.y"
 {
			switch (yypvt[-1]) {

			case STRU_F:
				reply(200, "STRU F ok.");
				break;

			default:
				reply(502, "Unimplemented STRU type.");
			}
		} break;
case 8:
# line 156 "ftpcmd.y"
 {
			switch (yypvt[-1]) {

			case MODE_S:
				reply(200, "MODE S ok.");
				break;

			default:
				reply(502, "Unimplemented MODE type.");
			}
		} break;
case 9:
# line 168 "ftpcmd.y"
 {
			ack(yypvt[-3]);
		} break;
case 10:
# line 172 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				retrieve(0, yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 11:
# line 179 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				store(yypvt[-1], "w");
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 12:
# line 186 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				store(yypvt[-1], "a");
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 13:
# line 193 "ftpcmd.y"
 {
			if (yypvt[-1])
				retrieve("/bin/ls", "");
		} break;
case 14:
# line 198 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				retrieve("/bin/ls %s", yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 15:
# line 205 "ftpcmd.y"
 {
			if (yypvt[-1])
				retrieve("/bin/ls -lg", "");
		} break;
case 16:
# line 210 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				retrieve("/bin/ls -lg %s", yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 17:
# line 217 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				delete(yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 18:
# line 224 "ftpcmd.y"
 {
			if (yypvt[-1])
				cwd(pw->pw_dir);
		} break;
case 19:
# line 229 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				cwd(yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 21:
# line 237 "ftpcmd.y"
 {
			help(0);
		} break;
case 22:
# line 241 "ftpcmd.y"
 {
			help(yypvt[-1]);
		} break;
case 23:
# line 245 "ftpcmd.y"
 {
			ack(yypvt[-1]);
		} break;
case 24:
# line 249 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				makedir(yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 25:
# line 256 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				removedir(yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 26:
# line 263 "ftpcmd.y"
 {
			if (yypvt[-1])
				pwd();
		} break;
case 27:
# line 268 "ftpcmd.y"
 {
			if (yypvt[-1])
				cwd("..");
		} break;
case 28:
# line 273 "ftpcmd.y"
 {
			reply(221, "Goodbye.");
			dologout(0);
		} break;
case 29:
# line 278 "ftpcmd.y"
 {
			yyerrok;
		} break;
case 33:
# line 294 "ftpcmd.y"
 {
			register char *a, *p;

			a = (char *)&data_dest.sin_addr;
			a[0] = yypvt[-10]; a[1] = yypvt[-8]; a[2] = yypvt[-6]; a[3] = yypvt[-4];
			p = (   (   (char *)&data_dest.sin_port;
			p[0] = yypvt[-2]; p[1] = yypvt[-0];
			data_dest.sin_family = AF_INET;
		} break;
case 34:
# line 306 "ftpcmd.y"
 {
		yyval = FORM_N;
	} break;
case 35:
# line 310 "ftpcmd.y"
 {
		yyval = FORM_T;
	} break;
case 36:
# line 314 "ftpcmd.y"
 {
		yyval = FORM_C;
	} break;
case 37:
# line 320 "ftpcmd.y"
 {
		cmd_type = TYPE_A;
		cmd_form = FORM_N;
	} break;
case 38:
# line 325 "ftpcmd.y"
 {
		cmd_type = TYPE_A;
		cmd_form = yypvt[-0];
	} break;
case 39:
# line 330 "ftpcmd.y"
 {
		cmd_type = TYPE_E;
		cmd_form = FORM_N;
	} break;
case 40:
# line 335 "ftpcmd.y"
 {
		cmd_type = TYPE_E;
		cmd_form = yypvt[-0];
	} break;
case 41:
# line 340 "ftpcmd.y"
 {
		cmd_type = TYPE_I;
	} break;
case 42:
# line 344 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = 8;
	} break;
case 43:
# line 349 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = yypvt[-0];
	} break;
case 44:
# line 355 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = yypvt[-0];
	} break;
case 45:
# line 362 "ftpcmd.y"
 {
		yyval = STRU_F;
	} break;
case 46:
# line 366 "ftpcmd.y"
 {
		yyval = STRU_R;
	} break;
case 47:
# line 370 "ftpcmd.y"
 {
		yyval = STRU_P;
	} break;
case 48:
# line 376 "ftpcmd.y"
 {
		yyval = MODE_S;
	} break;
case 49:
# line 380 "ftpcmd.y"
 {
		yyval = MODE_B;
	} break;
case 50:
# line 384 "ftpcmd.y"
 {
		yyval = MODE_C;
	} break;
case 51:
# line 390 "ftpcmd.y"
 {
		if (yypvt[-0] && strncmp(yypvt[-0], "~", 1) == 0) {
			yyval = (int)*glob(yypvt[-0]);
			if (globerr != NULL) {
				reply(550, globerr);
				yyval = NULL;
			}
			free(yypvt[-0]);
		} else
			yyval = yypvt[-0];
	} break;
case 53:
# line 407 "ftpcmd.y"
 {
		if (yypvt[-1] && yypvt[-0])
			renamecmd(yypvt[-1], yypvt[-0]);
		else
			reply(503, "Bad sequence of commands.");
		if (yypvt[-1])
			free(yypvt[-1]);
		if (yypvt[-0])
			free(yypvt[-0]);
	} break;
case 54:
# line 420 "ftpcmd.y"
 {
		char *from = 0, *renamefrom();

		if (yypvt[-3] && yypvt[-1])
			from = renamefrom(yypvt[-1]);
		if (from == 0 && yypvt[-1])
			free(yypvt[-1]);
		yyval = (int)from;
	} break;
case 55:
# line 432 "ftpcmd.y"
 {
		yyval = yypvt[-1];
	} break;
case 56:
# line 438 "ftpcmd.y"
 {
		if (logged_in)
			yyval = 1;
		else {
			reply(530, "Please login with USER and PASS.");
			yyval = 0;
		}
	} break;
	}
	goto yystack;		/* reset registers in driver code */
}
oto skip_init;
			yyerrlab:
				/*
				** get globals into registers.
				** we have a user generated syntax type error
				*/
				yy_pv = yypv;
				yy_ps = yyps;
				yy_state = yystate;
				yynerrs++;
			skip_init:
			case 1:
unix/servers/README                                                                                    444     322     145         1010  3621344620   7450                                                                                                                                                                                                                                                                                                                                                                      	Here live the various network daemons.  The Makefile contains
details of their construction; however, be aware that these must
run SUID root so they can use "privileged" TCP ports.

	The daemons (servers) are normally started automatically
whenever Unix starts multi-user operation.  If you wish to do this
on your system, you will need to move the daemons to some convient
place and modifiy /etc/rc or /etc/inittab to start them up.

	The Makefile assumes that you have already made ../lib and have
libcmcnet.a built.
 = TYPE_E;
		cmd_form = FORM_N;
	} break;
case 40:
# line 335 "ftpcmd.y"
 {
		cmd_type = TYPE_E;
		cmd_form = yypvt[-0];
	} break;
case 41:
# line 340 "ftpcmd.y"
 {
		cmd_type = TYPE_I;
	} break;
case 42:
# line 344 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = 8;
	} break;
case 43:
# line 349 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = yypvt[-0];
	} break;
case 44:
# line 355 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = yypvt[-0];
	} break;
case 45:
# line 362 "ftpcmd.y"
 {
		yyval =unix/servers/Makefile                                                                                  444     322     145         1432  3621344620  10240                                                                                                                                                                                                                                                                                                                                                                      #	/*
#	 *	Copyright (c) 1984, Communication Machinery Corporation
#	 */
#	
#	/*
#	 *	This file contains material and information which is
#	 *	proprietary to Communication Machinery Corporation, and
#	 *	which may not be divulged without the express written
#	 *	permission of Communication Machinery Corporation.
#	 */

# Makefile 7/01/85

CFLAGS= -O -v -I../include
LIBS= -lcmcnet

none:
	@echo You have to make something

all: telnetd rshd rlogind tftpd 

telnetd: telnetd.o
	${CC} -o telnetd telnetd.o ${LIBS}
	chmod u+s telnetd

rshd: rshd.o
	${CC} -o rshd rshd.o ${LIBS}
	chmod u+s rshd

rlogind: rlogind.o
	${CC} -o rlogind rlogind.o ${LIBS}
	chmod u+s rlogind

tftpd:	tftpd.o
	${CC} -o tftpd tftpd.o ${LIBS}
	chmod u+s tftpd

clean:
	rm -f telnetd.o a.out core rshd.o rlogind.o tftpd.o
eak;
case 43:
# line 349 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = yypvt[-0];
	} break;
case 44:
# line 355 "ftpcmd.y"
 {
		cmd_type = TYPE_L;
		cmd_bytesz = yypvt[-0];
	} break;
case 45:
# line 362 "ftpcmd.y"
 {
		yyval =unix/servers/rlogind.c                                                                                 444     322     145        22574  3621344621  10435                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *		BSD 4.2 rlogind conversion to System V
 *
 *	HISTORY:
 *
 *	Initial Coding: Pre-historic, someone at UCB
 *
 *	Sys V conversion -- first pass by Doug Miller (CMC), August 1984
 *		-- conversion completed by John Mullen (CMC), 16 Nov 1984
 *
*/

#ifndef lint
static char sccsid[] = "@(#)rlogind.c 	(CMC)	5.0  11/16/84";
#endif

#include <stdio.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <sys/stat.h>
#include <CMC/socket.h>
#include <CMC/in.h>
#include <CMC/errno.h>
#include <pwd.h>
#include <CMC/signal.h>
#include <termio.h>
#include <fcntl.h>
#include <stdio.h>
#include <CMC/netdb.h>
#include <CMC/pty.h>

# define SLEEPTIME 1

extern	errno;
char	*ntoa();
struct	sockaddr_in sin = { AF_INET };

/*
 * remote login server:
 *	remuser\0
 *	locuser\0
 *	terminal type\0
 *	data
 */

main(argc, argv)
	int argc;
	char **argv;
{
	int f, options = 0;
	struct sockaddr_in from;
	struct servent *sp;
	int reaper();

	sp = getservbyname("login", "tcp");
	if (sp == 0) {
		fprintf(stderr, "rlogind: tcp/rlogin: unknown service\n");
		exit(1);
	}
#ifndef DEBUG
	if (fork())
		exit(0);
	setpgrp();
	for (f = 0; f < 10; f++)
		(void) close(f);
	(void) open("/", 0);
	fcntl(0, F_DUPFD, 1 );
	fcntl(0, F_DUPFD, 2 );
#endif
	sin.sin_port = sp->s_port;
	argc--, argv++;
	if (argc > 0 && !strcmp(argv[0], "-d")) {
		options |= SO_DEBUG;
		argc--, argv++;
	}
	if (argc > 0) {
		int port = atoi(argv[0]);

		if (port < 0) {
			fprintf(stderr, "%s: bad port #\n", argv[0]);
			exit(1);
		}
		sin.sin_port = htons((u_short)port);
		argv++, argc--;
	}
	f = socket(AF_INET, SOCK_STREAM, 0);
	if (f < 0) {
		perror("rlogind: socket");
		exit(1);
	}
	if (bind(f, &sin, sizeof (sin)) < 0) {
		perror("rlogind: bind");
		exit(1);
	}
	signal(SIGCLD, reaper);
	signal(SIGURGENT, SIG_IGN);

	listen(f, 10);
	for (;;) {
		int s, len = sizeof (from);

		s = accept(f, &from, &len);
		if (s < 0) {
			if (errno == EINTR)
				continue;
			perror("rlogind: accept");
			continue;
		}
		if (fork() == 0) {
			close(f);
			doit(s, &from);
		}
		close(s);
	}
}


char	buf[BUFSIZ];
char	user[24];
char	term[64] = "TERM=";
char	*speeds[] =
    { "0", "50", "75", "110", "134", "150", "200", "300",
      "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
int	cleanup();
int	ping();
int	netf;				/* Fid of net socket	*/
extern	errno;
char	*line;

doit(f, fromp)
	int f;
	struct sockaddr_in *fromp;
{
	char c;
	int i, p, cc, t, pid;
	int timeleft = 0;
	int stop = TIOCPKT_DOSTOP;
	register struct hostent *hp;
	extern char *strchr();

	alarm(60);
	read(f, &c, 1);
	if (c != 0)
		exit(1);
	alarm(0);
	fromp->sin_port = htons((u_short)fromp->sin_port);
	hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
		fromp->sin_family);
	if (hp == 0) {
		fatal(f, sprintf(buf, "Host name for your address (%s) unknown",
			ntoa(fromp->sin_addr)));
	}
	if (fromp->sin_family != AF_INET ||
	    fromp->sin_port >= IPPORT_RESERVED ||
	    hp == 0)
		fatal(f, "Permission denied");
	write(f, "", 1);
	for (c = 'p'; c <= 's'; c++) {
		struct stat stb;
		line = "/dev/ptyXX";
		line[strlen("/dev/pty")] = c;
		line[strlen("/dev/ptyp")] = '0';
		if (stat(line, &stb) < 0)
			break;
		for (i = 0; i < 16; i++) {
			line[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
			p = open(line, 2);
			if (p > 0)
				goto gotpty;
		}
	}
	fatal(f, "All network ports in use");
	/*NOTREACHED*/
gotpty:
	close(0);
	netf = fcntl(f, F_DUPFD, 0);

	getstr (f, user, sizeof (user), "remote user");
	getstr (f, user, sizeof (user), "local user");
	getstr (f, term+5, sizeof (term)-5, "terminal type");

	pid = fork();
	if (pid < 0)
		fatalperror(f, "", errno);
	if (pid) {
		char pibuf[1024], fibuf[1024], *pbp, *fbp;
		int pcc = 0, fcc = 0, on = 1, flgs;

		setpgrp();
		flgs = fcntl(f, F_GETFL, 0);
		fcntl(f, F_SETFL, (   (   flgs|O_NDELAY);
		ioctl(p, TIOCPKT, &on);
		flgs = fcntl(p, F_GETFL, 0);
		fcntl(p, F_SETFL, flgs|O_NDELAY);
		signal(SIGCLD, ping);
		signal(SIGALRM, cleanup);

		for (;;) {
			int ibits = 0, obits = 0;

			if (fcc)
				obits |= (1<<p);
			else
				ibits |= (1<<f);
			if (pcc >= 0)
				if (pcc)
					obits |= (1<<f);
				else
					ibits |= (1<<p);
			if (fcc < 0 && pcc < 0)
				break;


			if (ibits & (1<<f)) {	/* Wants net input	*/
				fcc = read(f, fibuf, sizeof (fibuf));
				if (fcc > 0)
					fbp = fibuf;	/* Got data	*/
				else
				if ( fcc < 0 && errno == EWOULDBLOCK ) {
					fcc = 0;
					ibits &= ~(1<<f);
				}
				else
					break;
			}

			if (ibits & (1<<p)) {	/* Wants ptty input	*/
				pcc = read(p, pibuf, sizeof (pibuf));
				pbp = pibuf;
				if (pcc <= 0) {
					pcc = 0;
					ibits &= ~(1<<p); /* No data	*/
				}
				else
				if (pibuf[0] == 0)
					pbp++, pcc--;
				else {
					if (pibuf[0]&(TIOCPKT_FLUSHWRITE|
						      TIOCPKT_NOSTOP|
						      TIOCPKT_DOSTOP)) {
						int nstop = pibuf[0] &
						    (TIOCPKT_NOSTOP|
						     TIOCPKT_DOSTOP);
						if (nstop)
							stop = nstop;
						pibuf[0] |= nstop;
						send(f,&pibuf[0],1,MSG_OOB);
					}
					pcc = 0;
				}
			}


			if (ibits == 0 && obits == 0) {
/*				timeleft = sleep(SLEEPTIME); */
				if ( timeleft > 0 )
					alarm (timeleft);
				continue;
			}

			if ((obits & (1<<f)) && pcc > 0) {
				cc = write(f, pbp, pcc);
				if (cc > 0) {
					pcc -= cc;
					pbp += cc;
				}
			}
			if ((obits & (1<<p)) && fcc > 0) {
				cc = write(p, fbp, fcc);
				if (cc > 0) {
					fcc -= cc;
					fbp += cc;
				}
			}
		}
		cleanup();
	}

	/*	Open slave pty and establish process/terminal group */

	setpgrp();
	line[strlen("/dev/")] = 't';
	t = open(line, 2);
	if (t < 0)
		fatalperror(f, line, errno);
	{
		struct termio b;
		char *speed;
		short speed_index = sizeof(speeds)/sizeof(char *);

		speed = strchr (term, '/');
		if ( speed ) {
			*speed++ = 0;
			for (speed_index=0;
				speed_index < sizeof(speeds)/sizeof(char *);
					speed_index++)
				if ( strcmp (speed, speeds[speed_index]) == 0)
					break;
		}
		if (speed_index == sizeof(speeds)/sizeof(char *))
			--speed_index;

		ioctl(t, TCGETA, &b);		/* set CRMOD | XTABS | ANYP */
		b.c_iflag = ICRNL | ISTRIP | IXON;
		b.c_oflag = OPOST | ONLCR | TAB3;
		b.c_cflag = CREAD | speed_index | CS8;
		b.c_lflag = ISIG | ICANON | ECHO | ECHOK;
		ioctl(t, TCSETAF, &b);
	}

	account (&line[5]);		/* 5 = strlen ("/dev/"); */
	close(f);
	close(p);
	for ( i=0; i<=2; i++ ) {
		close (i);
		fcntl(t, F_DUPFD, i);
	}
	close(t);
	execl("/bin/login", "login", user, term, 0);
	fatalperror(2, "/bin/login", errno);
	/*NOTREACHED*/
}

reaper()
{
	int pid, status;

	pid = wait (&status);
	signal (SIGCLD, reaper);
}

ping()
{
	wait(0);
	signal (SIGCLD, ping);
	alarm ( 3*SLEEPTIME );
}

cleanup()
{

	rmut();
	shutdown(netf, 2);
	kill(0, SIGKILL);
	exit(1);
}

fatal(f, msg)
	int f;
	char *msg;
{
	char buf[BUFSIZ];

	buf[0] = '\01';		/* error indicator */
	(void) sprintf(buf + 1, "rlogind: %s.\r\n", msg);
	(void) write(f, buf, strlen(buf));
	exit(1);
}

fatalperror(f, msg, errno)
	int f;
	char *msg;
	int errno;
{
	char buf[BUFSIZ];
	extern char *net_error();

	(void) sprintf(buf, "%s: %s", msg, net_error(errno));
	fatal(f, buf);
}

#include <utmp.h>

struct	utmp wtmp;
char	wtmpf[]	= "/etc/wtmp";
char	utmp[] = "/etc/utmp";
#define SCPYN(a, b)	strncpy(a, b, sizeof(a))
#define SCMPN(a, b)	strncmp(a, b, sizeof(a))

account (line)
register char *line;
{
	register f, mypid;
	register struct utmp *u;
	extern struct utmp *getutent();

	mypid = getpid();

	while ( (u = getutent()) != NULL ) {
		if ( u->ut_type == INIT_PROCESS && u->ut_pid == mypid )
			break;
	}

	if ( u == NULL )		/* no entry for this process */
		u = &wtmp;
	SCPYN (u->ut_line, line);
	SCPYN (u->ut_user, "LOGIN");
	SCPYN (u->ut_id, line+3);
	u->ut_type = LOGIN_PROCESS;
	u->ut_pid = mypid;
	u->ut_time = time ( 0 );
	pututline (u);
	endutent();
	if ((f = open(wtmpf, 1)) >= 0) {	/* if can access wtmp file */
		lseek(f, (long) 0, 2);		/* skip to end */
		write(f, (char *) u, sizeof (*u)); /* append logout record */
		close(f);
	}
}

rmut()
{
	register f;
	register struct utmp *w;
	struct utmp *getutline();

	SCPYN(wtmp.ut_line, line+5);		/* skeleton logout record */
	wtmp.ut_line[0] = 't';
	wtmp.ut_type = DEAD_PROCESS;
	(void) setutent();
	while ((w = getutline(&wtmp)) != NULL) { /* find entry for this line */
		SCPYN(w->ut_user, "");		/* empty login name */
		w->ut_type = DEAD_PROCESS;	/* and type fields */
		time(&(w->ut_time));		/* mark logout time */
		(void) pututline(w);		/* and write entry in utmp */
	}
	(void) endutent();	
	if ((f = open(wtmpf, 1)) >= 0) {	/* if can access wtmp file */
		lseek(f, (long) 0, 2);		/* skip to end */
		write(f, (char *) w, sizeof (*w)); /* append logout record */
		close(f);
	}
	chmod(line, 0666);
	chown(line, 0, 0);
	line[strlen("/dev/")] = 'p';
	chmod(line, 0666);
	chown(line, 0, 0);
}

/*
 * Convert network-format internet address
 * to base 256 d.d.d.d representation.
 */
char *
ntoa(in)
	struct in_addr in;
{
	static char b[18];
	register char *p;

	p = (char *)&in;
#define	UC(b)	(((int)b)&0xff)
	sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
	return (b);
}

getstr(fid, bp, cnt, err)
	char *bp;
	int cnt;
	char *err;
{
	char c;

	do {
		if (read(fid, &c, 1) != 1)
			exit(1);
		*bp++ = c;
		if (--cnt == 0) {
			fatal(fid, sprintf (buf, "%s too long\n", err));
			exit(1);
		}
	} while (c != 0);
}
					*( yy_ps -= yy_len ) + 1;
				if ( yy_state >= YYLAST ||
					yychk[ yy_state =
					yyact[ yy_state ] ] != -yy_n )
				{
					unix/servers/rshd.c                                                                                    444     322     145        16122  3621344621   7727                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	Converted from Berkeley 4.2 distribution to vanilla
 *	System V, assuming pseudo-teletypes (pty's) functionally
 *	equivalent to those in 4.2.
 *
 *	Initial Coding:
 *		Pre-historic, someone at UCB.
 *	Sys V Conversion:
 *		9/18/84 by John Mullen (CMC)
 */


#ifndef lint
static char sccsid[] = "@(#)rshd.c 5.0 (CMC) 84/09/18";
#endif

#include <CMC/longnames.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/param.h>
#include <CMC/types.h>
#include <CMC/socket.h>

#include <CMC/in.h>

#include <stdio.h>
#include <CMC/errno.h>
#include <pwd.h>
#include <CMC/signal.h>
# ifndef SIGCHLD
#	define SIGCHLD SIGCLD
# endif
#include <CMC/netdb.h>

# define SLEEPTIME 1

int	errno;
int	child_alive = 0;
struct	sockaddr_in sin = { AF_INET };
struct	passwd *getpwnam();
char	*strchr(), *strrchr(), *sprintf();
int	options;
/* VARARGS 1 */
int	error();
/*
 * remote shell server:
 *	remuser\0
 *	locuser\0
 *	command\0
 *	data
 */
main(argc, argv)
	int argc;
	char **argv;
{
	int f, linger;
	struct sockaddr_in from;
	struct servent *sp;
	int reaper();

	sp = getservbyname("shell", "tcp");
	if (sp == 0) {
		fprintf(stderr, "rshd: tcp/shell: unknown service\n");
		exit(1);
	}
#ifndef DEBUG
	if (fork())
		exit(0);
	setpgrp();
	for (f = 0; f < 10; f++)
		(void) close(f);
	(void) open("/", 0);
	(void) fcntl(0, F_DUPFD, 1);
	(void) fcntl(0, F_DUPFD, 2);
#endif
	sin.sin_port = sp->s_port;
	argc--, argv++;
	if (argc > 0 && !strcmp(argv[0], "-d")) {
		options |= SO_DEBUG;
		argc--, argv++;
	}
	if (argc > 0) {
		int port = atoi(argv[0]);

		if (port < 0) {
			fprintf(stderr, "%s: bad port #\n", argv[0]);
			exit(1);
		}
		sin.sin_port = htons((u_short)port);
		argc--, argv++;
	}
	f = socket(AF_INET, SOCK_STREAM, 0);
	if (f < 0) {
		perror("rshd: socket");
		exit(1);
	}
	if (options & SO_DEBUG && setsockopt(f, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
		perror("rshd: setsockopt (SO_DEBUG)");
	if (setsockopt(f, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
		perror("rshd: setsockopt (SO_KEEPALIVE)");
	linger = 60;			/* XXX */
	if (setsockopt(f, SOL_SOCKET, SO_LINGER, &linger, 0) < 0)
		perror("rshd: setsockopt (SO_LINGER)");
	if (bind(f, (caddr_t)&sin, sizeof (sin)) < 0) {
		perror("rshd: bind");
		exit(1);
	}
	signal(SIGCLD, reaper);
	signal(SIGURGENT, SIG_IGN);
	listen(f, 10);
	for (;;) {
		int g, len = sizeof (from);

		g = accept(f, &from, &len);
		if (g < 0) {
			if (errno == EINTR)
				continue;
			perror("rshd: accept");
			continue;
		}
		if (fork() == 0) {
			close(f);
			setpgrp ();
			doit(g, &from);
		}
		close(g);
	}
}

reaper ()
{
	wait (0);
	signal (SIGCLD, reaper);
}

ping ()
{
	wait (0);
	signal (SIGCLD, ping);
	alarm (3*SLEEPTIME);
}

deadkid ()
{
	extern child_alive;

	child_alive = 0;
}

char	username[20] = "USER=";
char	homedir[64] = "HOME=";
char	shell[64] = "SHELL=";
char	*envinit[] =
	    {homedir, shell, "PATH=:/bin:/usr/bin", username, 0};
char	**environ;

doit(f, fromp)
	int f;
	struct sockaddr_in *fromp;
{
	register short i;
	char cmdbuf[NCARGS+1], *cp;
	char locuser[16], remuser[16];
	struct passwd *pwd;
	int s = -1, backoff;
	struct hostent *hp;
	short port;
	int pv[2], pid, ready, readfrom, cc;
	char buf[BUFSIZ], sig;
	int one = 1;
	extern child_alive;

	(void) signal(SIGINT, SIG_DFL);
	(void) signal(SIGQUIT, SIG_DFL);
	(void) signal(SIGTERM, SIG_DFL);

	fromp->sin_port = ntohs((u_short)fromp->sin_port);
	if (fromp->sin_family != AF_INET ||
	    fromp->sin_port >= IPPORT_RESERVED) {
		fprintf(stderr, "rshd: malformed from address\n");
		exit(1);
	}

	(void) alarm(60);
	port = 0;
	for (;;) {
		char c;
		if (read(f, &c, 1) != 1) {
			perror("rshd: read");
			shutdown(f, 1+1);
			exit(1);
		}
		if (c == 0)
			break;
		port = port * 10 + c - '0';
	}
	(void) alarm(0);
	if (port != 0) {
		int lport = IPPORT_RESERVED - 1, retryshift;
		s = (   (   rresvport(&lport);
		if (s < 0) {
			perror("rshd: can't get stderr port");
			exit(1);
		}
		if (port >= IPPORT_RESERVED) {
			fprintf(stderr, "rshd: 2nd port not reserved\n");
			exit(1);
		}
		fromp->sin_port = htons((u_short)port);
		if (connect(s, fromp, sizeof (*fromp)) < 0) {
			perror("rshd: connect");
			exit(1);
		}
	}
	for ( i = 0; i <= 2; i++) {
		if ( i==f )
			f = fcntl (f, F_DUPFD, 3);
		if ( i==s )
			s = fcntl (s, F_DUPFD, 3);
		close (i);
		fcntl (f, F_DUPFD, i);
	}
	hp = gethostbyaddr(&fromp->sin_addr, sizeof (struct in_addr),
		fromp->sin_family);
	if (hp == 0) {
		error("rshd: Host name for your address unknown\n");
		exit(1);
	}
	getstr(remuser, sizeof(remuser), "remuser");
	getstr(locuser, sizeof(locuser), "locuser");
	getstr(cmdbuf, sizeof(cmdbuf), "command");
	setpwent();
	pwd = getpwnam(locuser);
	if (pwd == NULL) {
		error("rshd: Login incorrect.\n");
		exit(1);
	}
	endpwent();
	if (chdir(pwd->pw_dir) < 0) {
		error("rshd: No remote directory.\n");
		exit(1);
	}
	if (ruserok(hp->h_name, pwd->pw_uid == 0, remuser, locuser) < 0) {
		error("rshd: Permission denied.\n");
		exit(1);
	}
	(void) write(2, "\0", 1);
	if (port) {
		if (pipe(pv) < 0) {
			error("rshd: Can't make pipe.\n");
			exit(1);
		}
		pid = fork();
		if (pid == -1)  {
			error("rshd: Try again.\n");
			exit(1);
		}
		if (pid) {
			int flags;

			child_alive = 1;
			signal (SIGCLD, ping);
			signal (SIGALRM, deadkid);

			(void) close(0); (void) close(1); (void) close(2);
			(void) close(f); (void) close(pv[1]);

			flags = fcntl (pv[0], F_GETFL, 0);
			fcntl (pv[0], F_SETFL, flags | O_NDELAY);
			flags = fcntl (s, F_GETFL, 0);
			fcntl (s, F_SETFL, flags | O_NDELAY);

			readfrom = 1 << pv[0];
			do {
				i = sleep (SLEEPTIME);
				if ( i > 0 )
					alarm ( i );
				cc = read(s, &sig, 1);
				if (cc < 0 && errno != EWOULDBLOCK)
					break;
				if (cc > 0)
					kill (-pid, sig);

				errno = 0;
				cc = read(pv[0], buf, sizeof (buf));
				if (cc < 0 && errno != EWOULDBLOCK) {
					shutdown(s, 1+1);
					readfrom &= ~(1<<pv[0]);
				} else if (cc)
					(void) write(s, buf, cc);
			} while (readfrom && child_alive);
			exit(0);
		}
		(void) close(s); (void) close(pv[0]); (void) close (2);
		fcntl (pv[1], F_DUPFD, 2);
	}
	if (*pwd->pw_shell == '\0')
		pwd->pw_shell = "/bin/sh";
	(void) close(f);
	(void) setgid(pwd->pw_gid);
	(void) setuid(pwd->pw_uid);
	environ = envinit;
	strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
	strncat(shell, pwd->pw_shell, sizeof(shell)-7);
	strncat(username, pwd->pw_name, sizeof(username)-6);
	cp = strrchr(pwd->pw_shell, '/');
	if (cp)
		cp++;
	else
		cp = pwd->pw_shell;
	execl(pwd->pw_shell, cp, "-c", cmdbuf, 0);
	perror(pwd->pw_shell);
	exit(1);
protofail:
	error("rsh: protocol failure detected by remote\n");
	exit(1);
}

/* VARARGS 1 */
error(fmt)
	char *fmt;
{
	char buf[BUFSIZ];

	buf[0] = 1;
	(void) sprintf(buf+1, fmt);
	(void) write(2, buf, strlen(buf));
}

getstr(buf, cnt, err)
	char *buf;
	int cnt;
	char *err;
{
	char c;

	do {
		if (read(0, &c, 1) != 1)
			exit(1);
		*buf++ = c;
		if (--cnt == 0) {
			error("rshd: %s too long\n", err);
			exit(1);
		}
	} while (c != 0);
}
n:/usr/bin", username, 0};
char	**environ;

doit(f, fromp)
	int f;
	struct sockaddr_in *fromp;
{
	register short i;
	char cmdbuf[NCARGS+1], *cp;
	char locuser[16], remuser[16];
	struct passwd *pwd;
	int s = -1, backoff;
	struct hostent *hp;
	short port;
	int pv[2], pid, ready, readfrom, cc;
	char buf[BUFSIZ], sig;
	int one = 1;
	extern child_alive;

	(void) signal(SIGINT, SIG_DFL);
	(void) signal(SIGQUIT, SIG_DFL);
	(void) sigunix/servers/telnetd.c                                                                                 444     322     145        36036  3621344622  10435                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)telnetd.c	5.0 (CMC) 84/10/01";
#endif

/*
 * Stripped-down telnet server.
 * Based on BSD 4.2 telnet server.
 *
 *  HISTORY:
 *	Initial coding -- Pre-historic, someone at UCB.
 *
 *	Modified to use System 5 style non-blocking I/O and ioctl calls.
 *	Modified rmut to use System 5 routines for accessing utmp and
 *	wtmp files.
 *	NOTE:  rmut will need to be changed to run on other systems.
 *	   August, 1984		Deb Brown		CMC
 *
 *	Finish Sys V conversion -- October 1984 by John Mullen
 */

#include <CMC/sysdep.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <CMC/in.h>
#include <CMC/telnet.h>
#include <fcntl.h>
#include <stdio.h>
#include <CMC/signal.h>
#include <CMC/errno.h>
#include <termio.h>
#include <CMC/netdb.h>

# define SLEEPTIME 1

#ifndef SIGCHLD
#define SIGCHLD	SIGCLD		/* cause System 5 spells it differently */
#endif

#define	BELL	'\07'
#define BANNER	"\r\n\r\nCMC Telnet Server -- UNIX SYS V (%s)\r\n\r\r\n\r%s"

/*
 * Dummy codes and masks for doing equivilent of setting/resetting RAW
 * and ECHO|CRMOD modes in System 5.
 */
#define RAW		1
#define ECHO_CRMOD	2
#define CIRMASK	(PARMRK | INPCK | ISTRIP | INLCR | IGNCR | IUCLC | IXON | IXOFF)
#define CORMASK	(OLCUC | OFILL | TAB3)
#define CLRMASK	(ISIG | ICANON)
#define CIEMASK	(ICRNL)
#define COEMASK	(ONLCR)
#define CLEMASK	(ECHO | ECHOK)

char	hisopts[256];
char	myopts[256];

char	doopt[] = { IAC, DO, '%', 'c', 0 };
char	dont[] = { IAC, DONT, '%', 'c', 0 };
char	will[] = { IAC, WILL, '%', 'c', 0 };
char	wont[] = { IAC, WONT, '%', 'c', 0 };

/*
 * I/O data buffers, pointers, and counters.
 */
char	ptyibuf[BUFSIZ], *ptyip = ptyibuf;
char	ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf;
char	netibuf[BUFSIZ], *netip = netibuf;
char	netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
int	pcc, ncc;

int	pty, net;
int	inter;
int	reapchild();
extern	char **environ;
extern	int errno;
char	line[] = "/dev/ptyp0";
struct	sockaddr_in sin = { AF_INET };

main(argc, argv)
	char *argv[];
{
	int s, pid, options;
	struct servent *sp;

	sp = getservbyname("telnet", "tcp");
	if (sp == 0) {
		fprintf(stderr, "telnetd: tcp/telnet: unknown service\n");
		exit(1);
	}
	sin.sin_port = sp->s_port;
	argc--, argv++;
	if (argc > 0 && !strcmp(*argv, "-d")) {
		options |= SO_DEBUG;
		argc--, argv++;
	}
	if (argc > 0) {
		sin.sin_port = atoi(*argv);
		if ((short) sin.sin_port <= 0) {
			fprintf(stderr, "telnetd: %s: bad port #\n", *argv);
			exit(1);
		}
		sin.sin_port = htons((u_short)sin.sin_port);
	}
#ifndef DEBUG
	if (fork())
		exit(0);
	setpgrp();
	for (s = 0; s < 10; s++)
		(void) close(s);
	(void) open("/", O_RDONLY);
	fcntl(0, F_DUPFD, 1);
	fcntl(0, F_DUPFD, 2);
#endif
again:
	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s < 0) {
		perror("telnetd: socket");;
		sleep(5);
		goto again;
	}
	if (options & SO_DEBUG)
		if (setsockopt(s, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
			perror("telnetd: setsockopt (SO_DEBUG)");
	if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, 0, 0) < 0)
		perror("telnetd: setsockopt (SO_KEEPALIVE)");
	while (bind(s, (caddr_t)&sin, sizeof (sin)) < 0) {
		perror("telnetd: bind");
		sleep(5);
	}
	signal(SIGCHLD, reapchild);
	signal(SIGURGENT, SIG_IGN);
	listen(s, 10);
	for (;;) {
		struct sockaddr_in from;
		int s2, fromlen = sizeof (from);

		s2 = accept(s, (caddr_t)&from, &fromlen);
		if (s2 < 0) {
			if (errno == EINTR)
				continue;
			perror("telnetd: accept");
			sleep(1);
			continue;
		}
		if ((pid = fork()) < 0)
			printf("Out of processes\n");
		else if (pid == 0) {
			close (s);
			doit(s2, &from);
		}
		close(s2);
	}
	/*NOTREACHED*/
}

reapchild()
{
	int status, pid;

	pid = wait(&status);
	signal(SIGCHLD, reapchild);
}

char	*envinit[] = { "TERM=network", 0 };
int	sig_cleanup();
int	ping();

/*
 * Get a pty, scan input lines.
 */
doit(f, who)
	int f;
	struct sockaddr_in *who;
{
	char *cp = line, *host, *ntoa();
	int i, p, t;
	struct termio b;
	struct hostent *hp;

	for (i = 0; i < 16; i++) {
		cp[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
		p = open(cp, 2);
		if (p > 0)
			goto gotpty;
	}
	fatal(f, "All network ports in use");
	/*NOTREACHED*/
gotpty:
	(void) close(0);
	fcntl(f, F_DUPFD, 0);

	hp = gethostbyaddr(&who->sin_addr, sizeof (struct in_addr),
							who->sin_family);
	if (hp)
		host = hp->h_name;
	else
		host = ntoa(who->sin_addr);
	if ((i = fork()) < 0)
		fatalperror(f, "fork", errno);
	if (i) {
		setpgrp ();
		telnet(f, p);
	}

	setpgrp();
	cp[strlen("/dev/")] = 't';
	t = open(cp, 2);
	if (t < 0)
		fatalperror(f, cp, errno);

	ioctl(t, TCGETA, &b);		/* set CRMOD | XTABS | ANYP */
	b.c_iflag = ICRNL | ISTRIP | IXON;
	b.c_oflag = OPOST | ONLCR;
	b.c_cflag = CREAD | EXTB | CS8;
	b.c_lflag = ISIG | ICANON | ECHO | ECHOK;
	ioctl(t, TCSETAF, &b);

	account (cp+5);			/* 5 = strlen ("/dev/"); */
	close(f);
	close(p);
	for ( i = 0; i <= 2; i++ ) {
		(void) close(i);
		fcntl(t, F_DUPFD, i);
	}
	close(t);
	environ = envinit;
	execl("/bin/login", "login", 0);
	fatalperror(f, "/bin/login", errno);
	/*NOTREACHED*/
}

fatal(f, msg)
	int f;
	char *msg;
{
	char buf[BUFSIZ];

	(void) sprintf(buf, "telnetd: %s.\n", msg);
	(void) write(f, buf, strlen(buf));
	exit(1);
}

fatalperror(f, msg, errno)
	int f;
	char *msg;
	int errno;
{
	char buf[BUFSIZ];
	extern char *net_error();

	(void) sprintf(buf, "%s: %s", msg, net_error(errno));
	fatal(f, buf);
}

/*
 * Main loop.  Select from pty and network, and
 * hand data to telnet receiver finite state machine.
 */
telnet(f, p)
{
	int timeleft;
	char hostname[32];
	int fflags, pflags;

	net = f, pty = p;
	fflags = fcntl(f, F_GETFL, 0);
	pflags = fcntl(p, F_GETFL, 0);
	(void) fcntl(f, F_SETFL, fflags | O_NDELAY);
	(void) fcntl(p, F_SETFL, pflags | O_NDELAY);
	signal(SIGALRM, sig_cleanup);
	signal(SIGCLD, ping);

	/*
	 * Request to do remote echo.
	 */
	dooption(T (   (  ELOPT_ECHO);
	myopts[TELOPT_ECHO] = 1;
	/*
	 * Show banner that getty never gave.
	 */
	gethostname(hostname, sizeof (hostname));
	sprintf(nfrontp, BANNER, hostname, "");
	sleep(2);			/* give login time to start */
	nfrontp += strlen(nfrontp);
	for (;;) {
		register int c;
		register int ibits = 0, obits = 0;

		/*
		 * Never look for input if there's still
		 * stuff in the corresponding output buffer
		 */
		if (nfrontp - nbackp)
			obits |= (1 << f);
		else
			ibits |= (1 << p);
		if (pfrontp - pbackp)
			obits |= (1 << p);
		else
			ibits |= (1 << f);
		if (ncc < 0 && pcc < 0)
			break;

		/*
		 * Check for something to read from the network...
		 */
		if (ibits & (1 << f)) {
			ncc = read(f, netibuf, BUFSIZ);
			if (ncc < 0 && errno == EWOULDBLOCK) {
				ncc = 0;
				ibits &= ~(1<<f);
			}
			else {
				if (ncc <= 0)
					break;
				netip = netibuf;
			}
		}

		/*
		 * Check for something to read from the pty...
		 */
		if (ibits & (1 << p)) {
			pcc = read(p, ptyibuf, BUFSIZ);
			if (pcc < 0 && errno == EWOULDBLOCK) {
				pcc = 0;
				ibits &= ~(1<<p);
			}
			else {
				if (pcc <= 0)
					break;
				ptyip = ptyibuf;
			}
		}

		/*
		 * If no input ready and nothing waiting to be output ...
		 */
		if (ibits == 0 && obits == 0) {
# ifdef notdef
			timeleft = sleep(SLEEPTIME);
# endif notdef
			if ( timeleft > 0 )	/* only after SIGCLD */
				alarm ( timeleft );
			continue;
		}

		while (pcc > 0) {
			if ((&netobuf[BUFSIZ] - nfrontp) < 2)
				break;
			c = *ptyip++ & 0377, pcc--;
			if (c == IAC)
				*nfrontp++ = c;
			*nfrontp++ = c;
		}
		if ((nfrontp - nbackp) > 0)
			netflush();
		if (ncc > 0)
			telrcv();
		if ((pfrontp - pbackp) > 0)
			ptyflush();
	}
	cleanup();
}
	
/*
 * State for recv fsm
 */
#define	TS_DATA		0	/* base state */
#define	TS_IAC		1	/* look for double IAC's */
#define	TS_CR		2	/* CR-LF ->'s CR */
#define	TS_BEGINNEG	3	/* throw away begin's... */
#define	TS_ENDNEG	4	/* ...end's (suboption negotiation) */
#define	TS_WILL		5	/* will option negotiation */
#define	TS_WONT		6	/* wont " */
#define	TS_DO		7	/* do " */
#define	TS_DONT		8	/* dont " */

telrcv()
{
	register int c;
	static int state = TS_DATA;
	struct termio b;

	while (ncc > 0) {
		if ((&ptyobuf[BUFSIZ] - pfrontp) < 2)
			return;
		c = *netip++ & 0377, ncc--;
		switch (state) {

		case TS_DATA:
			if (c == IAC) {
				state = TS_IAC;
				break;
			}
			if (inter > 0)
				break;
			*pfrontp++ = c;
			if (!myopts[TELOPT_BINARY] && c == '\r')
				state = TS_CR;
			break;

		case TS_CR:
			if (c && c != '\n')
				*pfrontp++ = c;
			state = TS_DATA;
			break;

		case TS_IAC:
			switch (c) {

			/*
			 * Send the process on the pty side an
			 * interrupt.  Do this with a NULL or
			 * interrupt char; depending on the tty mode.
			 */
			case BREAK:
			case IP:
				interrupt();
				break;

			/*
			 * Are You There?
			 */
			case AYT:
				*pfrontp++ = BELL;
				break;

			/*
			 * Erase Character and
			 * Erase Line
			 */
			case EC:
			case EL:
				ptyflush();	/* half-hearted */
				ioctl (pty, TCGETA, &b);
				*pfrontp++ = (c == EC) ?
					b.c_cc[VERASE] : b.c_cc[VKILL];
				break;

			/*
			 * Check for urgent data...
			 */
			case DM:
				break;

			/*
			 * Begin option subnegotiation...
			 */
			case SB:
				state = TS_BEGINNEG;
				continue;

			case WILL:
			case WONT:
			case DO:
			case DONT:
				state = TS_WILL + (c - WILL);
				continue;

			case IAC:
				*pfrontp++ = c;
				break;
			}
			state = TS_DATA;
			break;

		case TS_BEGINNEG:
			if (c == IAC)
				state = TS_ENDNEG;
			break;

		case TS_ENDNEG:
			state = c == SE ? TS_DATA : TS_BEGINNEG;
			break;

		case TS_WILL:
			if (!hisopts[c])
				willoption(c);
			state = TS_DATA;
			continue;

		case TS_WONT:
			if (hisopts[c])
				wontoption(c);
			state = TS_DATA;
			continue;

		case TS_DO:
			if (!myopts[c])
				dooption(c);
			state = TS_DATA;
			continue;

		case TS_DONT:
			if (myopts[c]) {
				myopts[c] = 0;
				sprintf(nfrontp, wont, c);
				nfrontp += sizeof (wont) - 2;
			}
			state = TS_DATA;
			continue;

		default:
			printf("telnetd: panic state=%d\n", state);
			exit(1);
		}
	}
}

willoption(option)
	int option;
{
	char *fmt;

	switch (option) {

	case TELOPT_BINARY:
		mode(RAW, 0);
		goto common;

	case TELOPT_ECHO:
		mode(0, ECHO_CRMOD);
		/*FALL THRU*/

	case TELOPT_SGA:
	common:
		hisopts[option] = 1;
		fmt = doopt;
		break;

	case TELOPT_TM:
		fmt = dont;
		break;

	default:
		fmt = dont;
		break;
	}
	sprintf(nfrontp, fmt, option);
	nfrontp += sizeof (dont) - 2;
}

wontoption(option)
	int option;
{
	char *fmt;

	switch (option) {

	case TELOPT_ECHO:
		mode(ECHO_CRMOD, 0);
		goto common;

	case TELOPT_BINARY:
		mode(0, RAW);
		/*FALL THRU*/

	case TELOPT_SGA:
	common:
		hisopts[option] = 0;
		fmt = dont;
		break;

	default:
		fmt = dont;
	}
	sprintf(nfrontp, fmt, option);
	nfrontp += sizeof (doopt) - 2;
}

dooption(option)
	int option;
{
	char *fmt;

	switch (option) {

	case TELOPT_TM:
		fmt = wont;
		break;

	case TELOPT_ECHO:
		mode(ECHO_CRMOD, 0);
		goto common;

	case TELOPT_BINARY:
		mode(RAW, 0);
		/*FALL THRU*/

	case TELOPT_SGA:
	common:
		fmt = will;
		break;

	default:
		fmt = wont;
		break;
	}
	sprintf(nfrontp, fmt, option);
	nfrontp += sizeof (doopt) - 2;
}

/*
 * mode() has been modified significantly to use System 5 style ioctl
 * structures.  It knows that it is only called to turn on or off the old
 * RAW mode or the combined ECHO | CRMOD modes, and does just these two.
 */
mode(on, off)
	int on, off;
{
	struct termio b;

	ptyflush();
/*
	ioctl(pty, TCGETA, &b);
	switch(on) {
	case RAW:
		b.c_iflag &= ~CIRMASK;
		b.c_oflag &= ~CORMASK;
		b.c_lflag &= ~CLRMASK;
		break;
	case ECHO_CRMOD:
		b.c_iflag |= CIEMASK;
		b.c_oflag |= COEMASK | OPOST;
		b.c_lflag |= CLEMASK;
		break;
	}
	switch(off) {
	case RAW:
		b.c_iflag |= ISTRIP | INLCR;
		b.c_oflag |= TAB3;
		b.c_lflag |= CLRMASK;
		break;
	case ECHO_CRMOD:
		b.c_iflag &= ~CIEMASK;
		b.c_oflag &= ~COEMASK;
		b.c_lflag &= ~(CLEMASK | ECHOE | ECHONL);
		break;
	}
	ioctl (pty, TCSETAF, &b);
*/
}

/*
 * Send interrupt to process on other side of pty.
 * If it is in raw mode, just write NULL;
 * otherwise, write intr char.
 */
interrupt()
{
	struct termio b;

	ptyflush();	/* half-hearted */
	ioctl(pty, TCGETA, &b);
	if (israw(&b)) {
		*pfrontp++ = '\0';
		return;
	}
	*pfrontp = (char) b.c_cc[VINTR] < 0 ?
		'\177' : b.c_cc[VINTR];
}

israw(b)
	struct termio *b;
{
	if ((b->c_iflag & CIRMASK) == 0 &&
	    (b->c_oflag & CORMASK) == 0 &&
	    (b->c_lflag & CLRMASK) == 0)
		return (1);
	return (0);
}

ptyflush()
{
	int n;

	if ((n = pfrontp - pbackp) > 0)
		n = write(pty, pbackp, n);
	if (n < 0)
		return;
	pbackp += n;
	if (pbackp == pfrontp)
		pbackp = pfrontp = ptyobuf;
}

netflush()
{
	register int n;

	if ((n = nfrontp - nbackp) > 0)
		n = write(net, nbackp, n);
	if (n < 0) {
		if (errno == EWOULDBLOCK)
			return;
		/* should blow this guy away... */
		return;
	}
	nbackp += n;
	if (nbackp == nfrontp)
		nbackp = nfrontp = netobuf;
}

ping()
{
	int status;
	register pid;

	pid = wait(&status);
	signal (SIGCLD, ping);
	alarm (3*SLEEPTIME);
}

sig_cleanup()
{
	signal (SIGALRM, sig_cleanup);
	cleanup();
}

cleanup()
{

	rmut();
	shutdown (net, 2);
	kill(0, SIGKILL);
	exit(1);
}

#include <utmp.h>

struct	utmp wtmp;
char	wtmpf[] = "/etc/wtmp";
char	utmp[] = "/etc/utmp";
#define SCPYN(a, b)	strncpy(a, b, sizeof (a))
#define SCMPN(a, b)	strncmp(a, b, sizeof (a))

account (line)
register char *line;
{
	register f, mypid;
	register struct utmp *u;
	extern struct utmp *getutent();

	mypid = getpid();

	while ( (u = getutent()) != NULL ) {
		if ( u->ut_type == INIT_PROCESS && u->ut_pid == mypid )
			break;
	}

	if ( u == NULL )		/* no entry for this process */
		u = &wtmp;
	SCPYN (u->ut_line, line);
	SCPYN (u->ut_user, "LOGIN");
	SCPYN (u->ut_id, line+3);
	u->ut_type = LOGIN_PROCESS;
	u->ut_pid = mypid;
	u->ut_time = time ( 0 );
	pututline (u);
	endutent();
	if ((f = open(wtmpf, 1)) >= 0) {	/* if can access wtmp file */
		lseek(f, (long) 0, 2);		/* skip to end */
		write(f, (char *) u, sizeof (*u)); /* append logout record */
		close(f);
	}
}

rmut()
{
	register f;
	register struct utmp *w;
	struct utmp *getutline();

	SCPYN(wtmp.ut_line, line+5);		/* skeleton logout record */
	wtmp.ut_line[0] = 't';
	wtmp.ut_type = DEAD_PROCESS;
	(void) setutent();
	while ((w = getutline(&wtmp)) != NULL) { /* find entry for this line */
		SCPYN(w->ut_user, "");		/* empty login name */
		w->ut_type = DEAD_PROCESS;	/* and type fields */
		time(&(w->ut_time));		/* mark logout time */
		(void) pututline(w);		/* and write entry in utmp */
		wtmp = *w;			/* save this one */
	}
	(void) endutent();	
	if ((f = open(wtmpf, 1)) >= 0) {	/* if can access wtmp file */
		lseek(f, (long) 0, 2);		/* skip to end */
		write(f, (char *) &wtmp, sizeof (wtmp)); /* append record */
		close(f);
	}
	chmod(line, 0666);
	chown(line, 0, 0);
	line[strlen("/dev/")] = 'p';
	chmod(line, 0666);
	chown(line, 0, 0);
}

/*
 * Convert network-format internet address
 * to base 256 d.d.d.d representation.
 */
char *
ntoa(in)
	struct in_addr in;
{
	static char b[18];
	register char *p;

	p = (char *)&in;
#define	UC(b)	(((int)b)&0xff)
	sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
	return (b);
}
pvt[-1]);
		} break;
case 21:
# line 237 "ftpcmd.y"
 {
			help(0);
		} break;
case 22:
# line 241 "ftpcmd.y"
 {
			help(yypvt[-1]);
		} break;
case 23:
# line 245 "ftpcmd.y"
 {
			ack(yypvt[-1]);
		} break;
case 24:
# line 249 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				makedir(yypvt[-1]);
			if (yypvt[-1] != NULL)
				free(yypvt[-1]);
		} break;
case 25:
# line 256 "ftpcmd.y"
 {
			if (yypvt[-3] && yypvt[-1] != NULL)
				removedir(yypvt[-1]);
			if (yypvt[-1] != Nunix/servers/tftpd.c                                                                                   444     322     145        15723  3621344623  10120                                                                                                                                                                                                                                                                                                                                                                       (   (  #ifndef lint
static char sccsid[] = "@(#)tftpd.c	4.11 (Berkeley) 7/2/83";
#endif

/*
 * Trivial file transfer protocol server.
 */

#include <CMC/longnames.h>
#include <CMC/sysdep.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <CMC/in.h>
#include <CMC/tftp.h>
#include <CMC/signal.h>
# ifndef SIGCHLD
#	define SIGCHLD SIGCLD
# endif
#include <stdio.h>
#include <CMC/errno.h>
#include <ctype.h>
#include <CMC/netdb.h>
#include <setjmp.h>

#define	TIMEOUT		5

extern	int errno;
struct	sockaddr_in sin = { AF_INET };
int	f;
int	rexmtval = TIMEOUT;
int	maxtimeout = 5*TIMEOUT;
char	buf[BUFSIZ];

int	child_alive = 0;

main(argc, argv)
	char *argv[];
{
	struct sockaddr_in from;
	register struct tftphdr *tp;
	register int n;
	struct servent *sp;
	int	reaper();

	sp = getservbyname("tftp", "udp");
	if (sp == 0) {
		fprintf(stderr, "tftpd: udp/tftp: unknown service\n");
		exit(1);
	}
	sin.sin_port = sp->s_port;
#ifndef DEBUG
	if (fork())
		exit(0);
	setpgrp();
	for (f = 0; f < 10; f++)
		(void) close(f);
	(void) open("/", 0);
	(void) fcntl(0, F_DUPFD, 1);
	(void) fcntl(0, F_DUPFD, 2);
#endif
	signal(SIGCHLD, reaper);
	signal(SIGURGENT, SIG_IGN);
	for (;;) {
		int fromlen;

		f = socket(AF_INET, SOCK_DGRAM, 0);
		if (f < 0) {
			perror("tftpd: socket");
			sleep(5);
			continue;
		}
		if (setsockopt(f, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0)
			perror("tftpd: setsockopt (SO_REUSEADDR)");
		sleep(1);			/* let child do connect */
		while (bind(f, (caddr_t)&sin, sizeof (sin), 0) < 0) {
			perror("tftpd: bind");
			sleep(5);
		}
		do {
			fromlen = sizeof (from);
			n = recvfrom(f, buf, sizeof (buf), 0,
			    (caddr_t)&from, &fromlen);
		} while (n <= 0);
		tp = (struct tftphdr *)buf;
		tp->th_opcode = ntohs(tp->th_opcode);
		if (tp->th_opcode == RRQ || tp->th_opcode == WRQ)
			if (fork() == 0) {
				setpgrp();
				tftp(&from, tp, n);
			}
		(void) close(f);
	}
}

reaper()
{
	wait(0);
	signal(SIGCLD, reaper);
}

int	validate_access();
int	sendfile(), recvfile();

struct formats {
	char	*f_mode;
	int	(*f_validate)();
	int	(*f_send)();
	int	(*f_recv)();
} formats[] = {
	{ "netascii",	validate_access,	sendfile,	recvfile },
	{ "octet",	validate_access,	sendfile,	recvfile },
#ifdef notdef
	{ "mail",	validate_user,		sendmail,	recvmail },
#endif
	{ 0 }
};

int	fd;			/* file being transferred */

/*
 * Handle initial connection protocol.
 */
tftp(client, tp, size)
	struct sockaddr_in *client;
	struct tftphdr *tp;
	int size;
{
	register char *cp;
	int first = 1, ecode;
	register struct formats *pf;
	char *filename, *mode;

	if (connect(f, (caddr_t)client, sizeof (*client), 0) < 0) {
		perror("connect");
		exit(1);
	}
	filename = cp = tp->th_stuff;
again:
	while (cp < buf + size) {
		if (*cp == '\0')
			break;
		cp++;
	}
	if (*cp != '\0') {
		nak(EBADOP);
		exit(1);
	}
	if (first) {
		mode = ++cp;
		first = 0;
		goto again;
	}
	for (cp = mode; *cp; cp++)
		if (isupper(*cp))
			*cp = tolower(*cp);
	for (pf = formats; pf->f_mode; pf++)
		if (strcmp(pf->f_mode, mode) == 0)
			break;
	if (pf->f_mode == 0) {
		nak(EBADOP);
		exit(1);
	}
	ecode = (*pf->f_validate)(filename, client, tp->th_opcode);
	if (ecode) {
		nak(ecode);
		exit(1);
	}
	if (tp->th_opcode == WRQ)
		(*pf->f_recv)(pf);
	else
		(*pf->f_send)(pf);
	exit(0);
}

/*
 * Validate file access.  Since we
 * have no uid or gid, for now require
 * file to exist and be publicly
 * readable/writable.
 * Note also, full path name must be
 * given as we have no login directory.
 */
validate_access(file, client, mode)
	char *file;
	struct sockaddr_in *client;
	int mode;
{
	struct stat stbuf;

	if (*file != '/')
		return (EACCESS);
	if (stat(file, &stbuf) < 0)
		return (errno == ENOENT ? ENOTFOUND : EACCESS);
	if (mode == RRQ) {
		if ((stbuf.st_mode&(S_IREAD >> 6)) == 0)
			return (EACCESS);
	} else {
		if ((stbuf.st_mode&(S_IWRITE >> 6)) == 0)
			return (EACCESS);
	}
	fd = open(file, mode == RRQ ? 0 : 1);
	if (fd < 0)
		return (errno + 100);
	return (0);
}

int	timeout;
jmp_buf	timeoutbuf;

timer()
{

	timeout += rexmtval;
	if (timeout >= maxtimeout)
		exit(1);
	longjmp(timeoutbuf, 1);
}

/*
 * Send the requested file.
 */
sendfile(pf)
	struct format *pf;
{
	register struct tftphdr *tp;
	register int block = 1, size, n;

	signal(SIGALRM, timer);
	tp = (struct tftphdr *)buf;
	do {
		size = read(fd, tp->th_data, SEGSIZE);
		if (size < 0) {
			nak(errno + 100);
			goto abort;
		}
		tp->th_opcode = htons((u_short)DATA);
		tp->th_block = htons((u_short)block);
		timeout = 0;
		(void) setjmp(timeoutbuf);
		if (write(f, buf, size + 4) != size + 4) {
			perror("tftpd: write");
			goto abort;
		}
		do {
			alarm(rexmtval);
			n = read(f, buf, sizeof (buf));
			alarm(0);
			if (n < 0) {
				perror("tftpd: read");
				goto abort;
			}
			tp->th_opcode = ntohs((u_short)tp->th_opcode);
			tp->th_block = ntohs((u_short)tp->th_block);
			if (tp->th_opcode == ERROR)
				goto abort;
		} while (tp->th_opcode != ACK || tp->th_block != block);
		block++;
	} while (size == SEGSIZE);
abort:
	(void) close(fd);
}

/*
 * Receive a file.
 */
recvfile(pf)
	struct format *pf;
{
	register struct tftphdr *tp;
	register int block = 0, n, size;

	signal(SIGALRM, timer);
	tp = (struct tftphdr *)buf;
	do {
		timeout = 0;
		tp->th_opcode = htons((u_short)ACK);
		tp->th_block = htons((u_short)block);
		block++;
		(void) setjmp(timeoutbuf);
		if (write(f, buf, 4) != 4) {
			perror("tftpd: write");
			goto abort;
		}
		do {
			alarm(rexmtval);
			n = read(f, buf, sizeof (buf));
			alarm(0);
			if (n < 0) {
				perror("tftpd: read");
				goto abort;
			}
			tp->th_opcode = ntohs((u_short)tp->th_opcode);
			tp->th_block = ntohs((u_short)tp->th_block);
			if (tp->th_opcode == ERROR)
				goto abort;
		} while (tp->th_opcode != DATA || block != tp->th_block);
		size = write(fd, tp->th_data, n - 4);
		if (size < 0) {
			nak(errno + 100);
			goto abort;
		}
	} while (size == SEGSIZE);
abort:
	tp->th_opcode = htons((u_short)ACK);
	tp->th_block = htons((u_short)(block));
	(void) write(f, buf, 4);
	(void) close(fd);
}

struct errmsg {
	int	e_code;
	char	*e_msg;
} errmsgs[] = {
	{ EUNDEF,	"Undefined error code" },
	{ ENOTFOUND,	"File not found" },
	{ EACCESS,	"Access violation" },
	{ ENOSPACE,	"Disk full or allocation exceeded" },
	{ EBADOP,	"Illegal TFTP operation" },
	{ EBADID,	"Unknown transfer ID" },
	{ EEXISTS,	"File already exists" },
	{ ENOUSER,	"No such user" },
	{ -1,		0 }
};

/*
 * Send a nak packet (error message).
 * Error code passed in is one of the
 * standard TFTP codes, or a UNIX errno
 * offset by 100.
 */
nak(error)
	int error;
{
	register struct tftphdr *tp;
	int length;
	register struct errmsg *pe;
	extern char *sys_errlist[];

	tp = (struct tftphdr *)buf;
	tp->th_opcode = htons((u_short)ERROR);
	tp->th_code = htons((u_short)error);
	for (pe = errmsgs; pe->e_code >= 0; pe++)
		if (pe->e_code == error)
			break;
	if (pe->e_code < 0)
		pe->e_msg = sys_errlist[error - 100];
	strcpy(tp->th_msg, pe->e_msg);
	length = strlen(pe->e_msg);
	tp->th_msg[length] = '\0';
	length += 5;
	if (write(f, buf, length) != length)
		perror("nak");
}
LRM, sig_cleanup);
	cleanup();
}

cleanup()
{unix/users/                                                                                            750     322     145            0  4024637257   6171                                                                                                                                                                                                                                                                                                                                                                      unix/users/tftp/                                                                                       750     322     145            0  3722427542   7144                                                                                                                                                                                                                                                                                                                                                                      unix/users/tftp/Makefile                                                                               444     322     145         1075  3621344625  10675                                                                                                                                                                                                                                                                                                                                                                      #	/*
#	 *	Copyright (c) 1984, Communication Machinery Corporation
#	 */
#	
#	/*
#	 *	This file contains material and information which is
#	 *	proprietary to Communication Machinery Corporation, and
#	 *	which may not be divulged without the express written
#	 *	permission of Communication Machinery Corporation.
#	 */

# Makefile 9/01/85
#
DESTDIR=.
CFLAGS= -O -I../../include
LIBS= -lcmcnet
OBJS=	tftp

all: ${OBJS}

tftp:	main.o tftp.o
	${CC} -o tftp main.o tftp.o ${LIBS}
	chmod u+s tftp

# install:
#	install -s ftpd ${DESTDIR}/etc/ftpd

clean:
	rm -f *.o *.s a.out 
n = { AF_INET };
int	f;
int	rexmtval = TIMEOUT;
int	maxtimeout = 5*TIMEOUT;
char	buf[BUFSIZ];

int	child_alive = 0;

main(argc, argv)
	char *argv[];
{
	struct sockaddr_in from;
	register struct tftphdr *tp;
	register int n;
	struct servent *sp;
	int	reaper();

	sp = getservbyname("tftp", "udp");
	if (sp == 0) {
		fprintf(stderr, "tftpd: udp/tftp: unknown service\n");
		exit(1);
	}
	sin.sin_port = sp->s_port;
#ifndef DEBUG
	if (fork())
		exit(0);
	unix/users/tftp/main.c                                                                                 444     322     145        24772  3621344626  10357                                                                                                                                                                                                                                                                                                                                                                       (   (  #ifndef lint
static char sccsid[] = "@(#)main.c	4.7 (Berkeley) 8/11/83";
#endif

/*
 * TFTP User Program -- Command Interface.
 */

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <fcntl.h>

#include <CMC/in.h>

#include <CMC/signal.h>
#include <stdio.h>
#include <CMC/errno.h>
#include <setjmp.h>
#include <ctype.h>
#include <CMC/netdb.h>

#define	TIMEOUT		5		/* secs between rexmt's */

struct	sockaddr_in sin;
int	f;
int	trace;
int	verbose;
int	connected;
char	mode[32];
char	line[200];
int	margc;
char	*margv[20];
char	*prompt = "tftp";
jmp_buf	toplevel;
int	intr();
struct	servent *servp;

int	quit(), help(), setverbose(), settrace(), status();
int	get(), put(), setpeer(), setmode(), setrexmt(), settimeout();

#define HELPINDENT (sizeof("connect"))

struct cmd {
	char	*name;
	char	*help;
	int	(*handler)();
};

char	vhelp[] = "toggle verbose mode";
char	thelp[] = "toggle packet tracing";
char	chelp[] = "connect to remote tftp";
char	qhelp[] = "exit tftp";
char	hhelp[] = "print help information";
char	shelp[] = "send file";
char	rhelp[] = "receive file";
char	mhelp[] = "set file transfer mode";
char	sthelp[] = "show current status";
char	xhelp[] = "set per-packet retransmission timeout";
char	ihelp[] = "set total retransmission timeout";

struct cmd cmdtab[] = {
	{ "connect",	chelp,		setpeer },
	{ "mode",	mhelp,		setmode },
	{ "put",	shelp,		put },
	{ "get",	rhelp,		get },
	{ "quit",	qhelp,		quit },
	{ "verbose",	vhelp,		setverbose },
	{ "trace",	thelp,		settrace },
	{ "status",	sthelp,		status },
	{ "rexmt",	xhelp,		setrexmt },
	{ "timeout",	ihelp,		settimeout },
	{ "?",		hhelp,		help },
	0
};

struct	cmd *getcmd();
char	*tail();
char	*strchr();
char	*strrchr();

main(argc, argv)
	char *argv[];
{
	struct sockaddr_in sin;
	int top;

	servp = getservbyname("tftp", "udp");
	if (servp == 0) {
		fprintf(stderr, "tftp: udp/tftp: unknown service\n");
		exit(1);
	}
	f = socket(AF_INET, SOCK_DGRAM, 0, 0);
	if (f < 0) {
		perror("tftp: socket");
		exit(3);
	}
	memset((char *)&sin, '\0',  sizeof (sin));
	sin.sin_family = AF_INET;
	if (bind(f, &sin, sizeof (sin)) < 0) {
		perror("tftp: bind");
		exit(1);
	}
	strcpy(mode, "netascii");
	signal(SIGINT, intr);
	if (argc > 1) {
		if (setjmp(toplevel) != 0)
			exit(0);
		setpeer(argc, argv);
	}
	top = setjmp(toplevel) == 0;
	for (;;)
		command(top);
}

char	*hostname;
char	hnamebuf[32];

setpeer(argc, argv)
	int argc;
	char *argv[];
{
	register int c;
	struct hostent *host;

	if (argc < 2) {
		strcpy(line, "Connect ");
		printf("(to) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc > 3) {
		printf("usage: %s host-name [port]\n", argv[0]);
		return;
	}
	host = gethostbyname(argv[1]);
	if (host) {
		sin.sin_family = host->h_addrtype;
		memcpy(&sin.sin_addr, host->h_addr, host->h_length);
		hostname = host->h_name;
	} else {
		sin.sin_family = AF_INET;
		sin.sin_addr.s_addr = inet_addr(argv[1]);
		if (sin.sin_addr.s_addr == -1) {
			connected = 0;
			printf("%s: unknown host\n", argv[1]);
			return;
		}
		strcpy(hnamebuf, argv[1]);
		hostname = hnamebuf;
	}
	sin.sin_port = servp->s_port;
	if (argc == 3) {
		sin.sin_port = atoi(argv[2]);
		if (sin.sin_port < 0) {
			printf("%s: bad port number\n", argv[2]);
			connected = 0;
			return;
		}
		sin.sin_port = htons((u_short)sin.sin_port);
	}
	connected = 1;
}

struct	modes {
	char *m_name;
	char *m_mode;
} modes[] = {
	{ "ascii",	"netascii" },
	{ "binary",	"octect" },
	{ "mail",	"mail" },
	{ 0,		0 }
};

setmode(argc, argv)
	char *argv[];
{
	register struct modes *p;

	if (argc > 2) {
		char *sep;

		printf("usage: %s [", argv[0]);
		sep = " ";
		for (p = modes; p->m_name; p++) {
			printf("%s%s", sep, p->m_name);
			if (*sep == ' ')
				sep = " | ";
		}
		printf(" ]\n");
		return;
	}
	if (argc < 2) {
		printf("Using %s mode to transfer files.\n", mode);
		return;
	}
	for (p = modes; p->m_name; p++)
		if (strcmp(argv[1], p->m_name) == 0)
			break;
	if (p->m_name)
		strcpy(mode, p->m_mode);
	else
		printf("%s: unknown mode\n", argv[1]);
}

/*
 * Send file(s).
 */
put(argc, argv)
	char *argv[];
{
	int fd;
	register int n, addr;
	register char *cp, *targ;

	if (argc < 2) {
		strcpy(line, "send ");
		printf("(file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		putusage(argv[0]);
		return;
	}
	targ = argv[argc - 1];
	if (strchr(argv[argc - 1], ':')) {
		char *cp;
		struct hostent *hp;

		for (n = 1; n < argc - 1; n++)
			if (strchr(argv[n], ':')) {
				putusage(argv[0]);
				return;
			}
		cp = argv[argc - 1];
		targ = strchr(cp, ':');
		*targ++ = 0;
		hp = gethostbyname(cp);
		if (hp == 0) {
			printf("%s: Unknown host.\n", cp);
			return;
		}
		memcpy((caddr_t)&sin.sin_addr, hp->h_addr, hp->h_length);
		sin.sin_port = servp->s_port;
		sin.sin_family = hp->h_addrtype;
		connected = 1;
		hostname = hp->h_name;
	}
	if (!connected) {
		printf("No target machine specified.\n");
		return;
	}
	if (argc < 4) {
		cp = argc == 2 ? tail(targ) : argv[1];
		fd = open(cp, O_RDONLY);
		if (fd < 0) {
			fprintf(stderr, "tftp: "); perror(cp);
			return;
		}
		sendfile(fd, targ);
		return;
	}
	cp = strchr(targ, '\0'); 
	*cp++ = '/';
	for (n = 1; n < argc - 1; n++) {
		strcpy(cp, tail(argv[n]));
		fd = open(argv[n], O_RDONLY);
		if (fd < 0) {
			fprintf(stderr, "tftp: "); perror(argv[n]);
			continue;
		}
		sendfile(fd, targ);
	}
}

putusage(s)
	char *s;
{
	printf("usage: %s file ... host:target, or\n", s);
	printf("       %s file ... target (when already connected)\n", s);
}

/*
 * Receive file(s).
 */
get(argc, argv)
	char *argv[];
{
	int fd;
	register int n, addr;
	register char *cp;
	char *src;

	if (argc < 2) {
		strcpy(line, "get ");
		printf("(files) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		getusage(argv[0]);
		return;
	}
	if (!connected)
		for (n = 1; n < argc - 1; n++)
			if (strchr(argv[n], ':') == 0) {
				getusage(argv[0]);
				return;
			}
	for (n = 1; argc == 2 || n < argc - 1; n++) {
		src = strchr(argv[n], ':');
		if (src == NULL)
			src = argv[n];
		else {
			struct hostent *hp;

			*src++ = 0;
			hp = gethostbyname(argv[n]);
			if (hp == 0) {
				printf("%s: Unknown host.\n", argv[n]);
				continue;
			}
			memcpy((caddr_t)&sin.sin_addr,hp->h_addr,hp->h_length);
			sin.sin_family = hp->h_addrtype;
			sin.sin_port = servp->s_port;
			connected = 1;
			hostname = hp->h_name;
		}
		if (argc < 4) {
			cp = argc == 3 ? argv[2] : tail(src);
			fd = creat(cp, 0644);
			if (fd < 0) {
				fprintf(stderr, "tftp: "); perror(cp);
				return;
			}
			recvfile(fd, src);
			break;
		}
		cp = strchr(argv[argc - 1], '\0');
		*cp++ = '/';
		strcpy(cp, tail(src));
		fd = creat(src, 0644);
		if (fd < 0) {
			fprintf(stderr, "tftp: "); perror(src);
			continue;
		}
		recvfile(fd, src);
	}
}

getusage(s)
{
	printf("usage: %s host:file host:file ... file, or\n", s);
	printf("       %s file file ... file if connected\n", s);
}

int	rexmtval = TIMEOUT;

setrexmt(argc, argv)
	char *argv[];
{
	int t;

	if (argc < 2) {
		strcpy(line, "Rexmt-timeout ");
		printf("(value) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc != 2) {
		printf("usage: %s value\n", argv[0]);
		return;
	}
	t = atoi(argv[1]);
	if (t < 0)
		printf("%s: bad value\n", t);
	else
		rexmtval = t;
}

int	maxtimeout = 5 * TIMEOUT;

settimeout(argc, argv)
	char *argv[];
{
	int t;

	if (argc < 2) {
		strcpy(line, "Maximum-timeout ");
		printf("(value) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc != 2) {
		printf("usage: %s value\n", argv[0]);
		return;
	}
	t = atoi(argv[1]);
	if (t < 0)
		printf("%s: bad value\n", t);
	else
		maxtimeout = t;
}

status(argc, argv)
	char *argv[];
{
	if (connected)
		printf("Connected to %s.\n", hostname);
	else
		printf("Not connected.\n");
	printf("Mode: %s Verbose: %s Tracing: %s\n", mode,
		verbose ? "on" : "off", trace ? "on" : "off");
	printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n",
		rexmtval, maxtimeout);
}

intr()
{

	longjmp(toplevel, -1);
}

char *
tail(filename)
	char *filename;
{
	register char *s;
	
	while (*filename) {
		s = strrchr(filename, '/');
		if (s == NULL)
			break;
		if (s[1])
			return (s + 1);
		*s = '\0';
	}
	return (filename);
}

/*
 * Command parser.
 */
command(top)
	int top;
{
	register struct cmd *c;

	if (!top)
		putchar('\n');
	for (;;) {
		printf("%s> ", prompt);
		if (gets(line) == 0)
			continue;
		if (line[0] == 0)
			continue;
		makeargv();
		c = getcmd(margv[0]);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			continue;
		}
		if (c == 0) {
			printf("?Invalid command\n");
			continue;
		}
		(*c->handler)(margc, margv);
	}
}

struct cmd *
getcmd(name)
	register char *name;
{
	register char *p, *q;
	register struct cmd *c, *found;
	register int nmatches, longest;

	longest = 0;
	nmatches = 0;
	found = 0;
	for (c = cmdtab; p = c->name; c++) {
		for (q = name; *q == *p++; q++)
			if (*q == 0)		/* exact match? */
				return (c);
		if (!*q) {			/* the name was a prefix */
			if (q - name > longest) {
				longest = q - name;
				nmatches = 1;
				found = c;
			} else if (q - name == longest)
				nmatches++;
		}
	}
	if (nmatches > 1)
		return ((struct cmd *)-1);
	return (found);
}

/*
 * Slice a string up into argc/argv.
 */
makeargv()
{
	register char *cp;
	register char **argp = margv;

	margc = 0;
	for (cp = line; *cp;) {
		while (isspace(*cp))
			cp++;
		if (*cp == '\0')
			break;
		*argp++ = cp;
		margc += 1;
		while (*cp != '\0' && !isspace(*cp))
			cp++;
		if (*cp == '\0')
			break;
		*cp++ = '\0';
	}
	*argp++ = 0;
}

/*VARARGS*/
quit()
{
	exit(0);
}

/*
 * Help command.
 */
help(argc, argv)
	int argc;
	char *argv[];
{
	register struct cmd *c;

	if (argc == 1) {
		printf("Commands may be abbreviated.  Commands are:\n\n");
		for (c = cmdtab; c->name; c++)
			printf("%-*s\t%s\n", HELPINDENT, c->name, c->help);
		return;
	}
	while (--argc > 0) {
		register char *arg;
		arg = *++argv;
		c = getcmd(arg);
		if (c == (struct cmd *)-1)
			printf("?Ambiguous help command %s\n", arg);
		else if (c == (struct cmd *)0)
			printf("?Invalid help command %s\n", arg);
		else (   (  
			printf("%s\n", c->help);
	}
}

/*
 * Call routine with argc, argv set from args (terminated by 0).
 */
/* VARARGS2 */
call(routine, args)
	int (*routine)();
	int args;
{
	register int *argp;
	register int argc;

	for (argc = 0, argp = &args; *argp++ != 0; argc++)
		;
	(*routine)(argc, &args);
}

/*VARARGS*/
settrace()
{
	trace = !trace;
	printf("Packet tracing %s.\n", trace ? "on" : "off");
}

/*VARARGS*/
setverbose()
{
	verbose = !verbose;
	printf("Verbose mode %s.\n", verbose ? "on" : "off");
}
];
chaunix/users/tftp/tftp.c                                                                                 444     322     145        15237  3621344627  10405                                                                                                                                                                                                                                                                                                                                                                      #ifndef lint
static char sccsid[] = "@(#)tftp.c	4.7 (Berkeley) 8/11/83";
#endif

/*
 * TFTP User Program -- Protocol Machines
 */

#include <CMC/longnames.h>
#include <CMC/sysdep.h>
#include <CMC/types.h>
#include <CMC/socket.h>

#include <CMC/in.h>

#include <CMC/tftp.h>

#include <CMC/signal.h>
#include <stdio.h>
#include <CMC/errno.h>
#include <setjmp.h>

extern	int errno;
extern	struct sockaddr_in sin;
extern	char mode[];
int	f;
int	trace;
int	verbose;
int	connected;
char	buf[BUFSIZ];
int	rexmtval;
int	maxtimeout;
int	timeout;
jmp_buf	toplevel;
jmp_buf	timeoutbuf;

timer()
{

	timeout += rexmtval;
	if (timeout >= maxtimeout) {
		printf("Transfer timed out.\n");
		longjmp(toplevel, -1);
	}
	longjmp(timeoutbuf, 1);
}

/*
 * Send the requested file.
 */
sendfile(fd, name)
	int fd;
	char *name;
{
	register struct tftphdr *tp = (struct tftphdr *)buf;
	register int block = 0, size, n, amount = 0;
	struct sockaddr_in from;
	time_t start = time(0), delta;
	int fromlen;

	signal(SIGALRM, timer);
	do {
		if (block == 0)
			size = makerequest(WRQ, name) - 4;
		else {
			size = read(fd, tp->th_data, SEGSIZE);
			if (size < 0) {
				nak(errno + 100);
				break;
			}
			tp->th_opcode = htons((u_short)DATA);
			tp->th_block = htons((u_short)block);
		}
		timeout = 0;
		(void) setjmp(timeoutbuf);
		if (trace) {
			tpacket("sent", tp, size + 4);
			dumpaddr("Destination ", &sin, sizeof(sin));
		}
		n = sendto(f, buf, size + 4, 0, (caddr_t)&sin, sizeof (sin));
		if (n != size + 4) {
			perror("tftp: sendto");
			goto abort;
		}
		do {
			alarm(rexmtval);
			do {
				fromlen = sizeof (from);
				n = recvfrom(f, buf, sizeof (buf), 0,
				    (caddr_t)&from, &fromlen);
			} while (n <= 0);
			alarm(0);
			if (n < 0) {
				perror("tftp: recvfrom");
				goto abort;
			}
			if (trace) {
				tpacket("received", tp, n);
				dumpaddr("Source ", &from, fromlen);
			}
			/* should verify packet came from server */
			tp->th_opcode = ntohs(tp->th_opcode);
			tp->th_block = ntohs(tp->th_block);
			if (tp->th_opcode == ERROR) {
				printf("Error code %d: %s\n", tp->th_code,
					tp->th_msg);
				goto abort;
			}
		} while (tp->th_opcode != ACK && block != tp->th_block);
		if (block > 0)
			amount += size;
		block++;
	} while (size == SEGSIZE || block == 1);
abort:
	(void) close(fd);
	if (amount > 0) {
		delta = time(0) - start;
		printf("Sent %d bytes in %d seconds.\n", amount, delta);
	}
}

/*
 * Receive a file.
 */
recvfile(fd, name)
	int fd;
	char *name;
{
	register struct tftphdr *tp = (struct tftphdr *)buf;
	register int block = 1, n, size, amount = 0;
	struct sockaddr_in from;
	time_t start = time(0), delta;
	int fromlen, firsttrip = 1;

	signal(SIGALRM, timer);
	do {
		if (firsttrip) {
			size = makerequest(RRQ, name);
			firsttrip = 0;
		} else {
			tp->th_opcode = htons((u_short)ACK);
			tp->th_block = htons((u_short)(block));
			size = 4;
			block++;
		}
		timeout = 0;
		(void) setjmp(timeoutbuf);
		if (trace) {
			tpacket("sent", tp, size);
			dumpaddr("Destination ", &sin, sizeof(sin));
		}
		if (sendto(f, buf, size, 0, (caddr_t)&sin,
		    sizeof (sin)) != size) {
			alarm(0);
			perror("tftp: sendto");
			goto abort;
		}
		do {
			alarm(rexmtval);
			do
				n = recvfrom(f, buf, sizeof (buf), 0,
				    (caddr_t)&from, &fromlen);
			while (n <= 0);
			alarm(0);
			if (n < 0) {
				perror("tftp: recvfrom");
				goto abort;
			}
			if (trace) {
				tpacket("received", tp, n);
				dumpaddr("Source ", &from, fromlen);
			}
			/* should verify client address */
			tp->th_opcode = ntohs(tp->th_opcode);
			tp->th_block = ntohs(tp->th_block);
			if (tp->th_opcode == ERROR) {
				printf("Error code %d: %s\n", tp->th_code,
					tp->th_msg);
				goto abort;
			}
		} while (tp->th_opcode != DATA && block != tp->th_block);
		size = write(fd, tp->th_data, n - 4);
		if (size < 0) {
			nak(errno + 100);
			break;
		}
		amount += size;
	} while (size == SEGSIZE);
abort:
	tp->th_opcode = htons((u_short)ACK);
	tp->th_block = htons((u_short)block);
	(void) sendto(f, buf, 4, 0, &sin, sizeof (sin));
	(void) close(fd);
	if (amount > 0) {
		delta = time(0) - start;
		printf("Received %d bytes in %d seconds.\n", amount, delta);
	}
}

makerequest(request, name)
	int request;
	char *name;
{
	register struct tftphdr *tp;
	int size;
	register char *cp;

	tp = (struct tftphdr *)buf;
	tp->th_opcode = htons((u_short)request);
	strcpy(tp->th_stuff, name);
	size = strlen(name);
	cp = tp->th_stuff + strlen(name);
	*cp++ = '\0';
	strcpy(cp, mode);
	cp += sizeof ("netascii") - 1;
	*cp++ = '\0';
	return (cp - buf);
}

struct errmsg {
	int	e_code;
	char	*e_msg;
} errmsgs[] = {
	{ EUNDEF,	"Undefined error code" },
	{ ENOTFOUND,	"File not found" },
	{ EACCESS,	"Access violation" },
	{ ENOSPACE,	"Disk full or allocation exceeded" },
	{ EBADOP,	"Illegal TFTP operation" },
	{ EBADID,	"Unknown transfer ID" },
	{ EEXISTS,	"File already exists" },
	{ ENOUSER,	"No such user" },
	{ -1,		0 }
};

/*
 * Send a nak packet (error message).
 * Error code passed in is one of the
 * standard TFTP codes, or a UNIX errno
 * offset by 100.
 */
nak(error)
	int error;
{
	register struct tftphdr *tp;
	int length;
	register struct errmsg *pe;
	extern char *sys_errlist[];

	tp = (struct tftphdr *)buf;
	tp->th_opcode = htons((u_short)ERROR);
	tp->th_code = htons((u_short)error);
	for (pe = errmsgs; pe->e_code >= 0; pe++)
		if (pe->e_code == error)
			break;
	if (pe->e_code < 0)
		pe->e_msg = sys_errlist[error - 100];
	strcpy(tp->th_msg, pe->e_msg);
	length = strlen(pe->e_msg) + 4;
	if (trace)
		tpacket("sent", tp, length);
	if (send(f, &sin, buf, length) != length)
		perror("nak");
}

tpacket(s, tp, n)
	struct tftphdr *tp;
	int n;
{
	static char *opcodes[] =
	   { "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR" };
	register char *cp, *file;
	u_short op = ntohs(tp->th_opcode);
	char *strchr();

	if (op < RRQ || op > ERROR)
		printf("%s opcode=%x ", s, op);
	else
		printf("%s %s ", s, opcodes[op]);
	switch (op) {

	case RRQ:
	case WRQ:
		n -= 2;
		file = cp = tp->th_stuff;
		cp = strchr(cp, '\0');
		printf("<file=%s, mode=%s>\n", file, cp + 1);
		break;

	case DATA:
		printf("<block=%d, %d bytes>\n", ntohs(tp->th_block), n - 4);
		break;

	case ACK:
		printf("<block=%d>\n", ntohs(tp->th_block));
		break;

	case ERROR:
		printf("<code=%d, msg=%s>\n", ntohs(tp->th_code), tp->th_msg);
		break;
	}
}


dumpaddr(msg, from, len)
register char	*msg;
register struct
sockaddr_in	*from;
register int	len;
{
	if (msg)
		printf("%s", msg);
	printf("Host: ");
	phex(&from->sin_addr.s_addr, 4);
	printf(" Port: %d\n", from->sin_port);
}


phex(bp, cnt)
register char	*bp;
int		cnt;
{
	register int	i;
	register char	c1, c2;

	static char hex_tab[] = "0123456789ABCDEF";

	for (i = 0; i < cnt; i++) {
		c1 = ((*bp&0xF0)>>4);
		c2 = (*bp++ & 0x0F);
		printf("%c%c",hex_tab[c1], hex_tab[c2]);
	}
}
		continue;
		}
		recvfile(fd, src);
	}
}

getusage(s)
{
	printf("usage: %s host:file host:file ... file, or\n", s);
	printf("       %s file file ... file if connected\n", s);
}

int	rexmtval = TIMEOUT;

setrexmt(argc, argv)
	char *argv[];
{
	int t;

	if (argc < 2) {
		strcpy(line, "Rexmt-timeout ");
		printf("(value) ");
		gets(&line[strlen(line)]);
unix/users/ftp/                                                                                        750     322     145            0  3722427570   6761                                                                                                                                                                                                                                                                                                                                                                      unix/users/ftp/Makefile                                                                                444     322     145         1243  3621344630  10502                                                                                                                                                                                                                                                                                                                                                                      #	/*
#	 *	Copyright (c) 1984, Communication Machinery Corporation
#	 */
#	
#	/*
#	 *	This file contains material and information which is
#	 *	proprietary to Communication Machinery Corporation, and
#	 *	which may not be divulged without the express written
#	 *	permission of Communication Machinery Corporation.
#	 */

# Makefile 9/12/84
#
ALL=	ftp
CFLAGS= -O -I../../include
LIBS= -lcmcnet

all:	${ALL}

ftp:	cmds.o cmdtab.o ftp.o getpass.o glob.o main.o
	${CC} cmds.o cmdtab.o ftp.o getpass.o glob.o main.o -o ftp ${LIBS}
	chmod u+s ftp

ftp.o: ftp_var.h
cmds.o: ftp_var.h
cmdtab.o: ftp_var.h
ftp.o:	ftp_var.h
main.o: ftp_var.h

clean:
	rm -f *.o *.s errs core a.out t.?
	longjmp(toplevel, -1);
	}
	longjmp(timeoutbuf, 1);
}

/*
 * Send the requested file.
 */
sendfile(fd, name)
	int fd;
	char *name;
{
	register struct tftphdr *tp = (struct tftphdr *)buf;
	register int block = 0, size, n, amount = 0;
	struct sockaddr_in from;
	time_t start = time(0), delta;
	int fromlen;

	signal(SIGALRM, timer);
	do {
		if (block  (   (  unix/users/ftp/cmds.c                                                                                  444     322     145        41115  3621344631  10157                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)cmds.c	4.9 (Berkeley) 7/26/83";
#endif

/*
 * FTP User Program -- Command Routines.
 */

#include <CMC/sysdep.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/param.h>		/* for MAXPATHLEN */
#include <sys/stat.h>
#include <CMC/socket.h>

#include <CMC/ftp.h>
#include <CMC/in.h>		/* for defn of htons */

#include <signal.h>
#include <stdio.h>
#include <CMC/errno.h>
#include <CMC/netdb.h>

#include "ftp_var.h"

extern	char *globerr;
extern	char **glob();
extern	char *home;
extern	short gflag;
extern	char *remglob();
extern	char *getenv();
extern	char *strchr();
extern	char *strrchr();

/*
 * Connect to peer server and
 * auto-login, if possible.
 */
setpeer(argc, argv)
	int argc;
	char *argv[];
{
	struct hostent *host, *hookup();
	int port;

	if (cncted) {
		printf("Already connected to %s, use disconnect first.\n",
			hostname);
		return;
	}
	if (argc < 2) {
		strcat(line, " ");
		printf("(to) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc > 3) {
		printf("usage: %s host-name [port]\n", argv[0]);
		return;
	}
	port = servp->s_port;
	if (argc > 2) {
		port = atoi(argv[2]);
		if (port <= 0) {
			printf("%s: bad port number-- %s\n", argv[1], argv[2]);
			printf ("usage: %s host-name [port]\n", argv[0]);
			return;
		}
		port = htons(port);
	}
	host = hookup(argv[1], port);
	if (host) {
		cncted = 1;
		if (autologin)
			login(host);
	}
}

struct	types {
	char	*t_name;
	char	*t_mode;
	int	t_type;
	char	*t_arg;
} types[] = {
	{ "ascii",	"A",	TYPE_A,	0 },
	{ "binary",	"I",	TYPE_I,	0 },
	{ "image",	"I",	TYPE_I,	0 },
	{ "ebcdic",	"E",	TYPE_E,	0 },
	{ "tenex",	"L",	TYPE_L,	bytename },
	0
};

/*
 * Set transfer type.
 */
settype(argc, argv)
	char *argv[];
{
	register struct types *p;
	int comret;

	if (argc > 2) {
		char *sep;

		printf("usage: %s [", argv[0]);
		sep = " ";
		for (p = types; p->t_name; p++) {
			printf("%s%s", sep, p->t_name);
			if (*sep == ' ')
				sep = " | ";
		}
		printf(" ]\n");
		return;
	}
	if (argc < 2) {
		printf("Using %s mode to transfer files.\n", typename);
		return;
	}
	for (p = types; p->t_name; p++)
		if (strcmp(argv[1], p->t_name) == 0)
			break;
	if (p->t_name == 0) {
		printf("%s: unknown mode\n", argv[1]);
		return;
	}
	if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
		comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
	else
		comret = command("TYPE %s", p->t_mode);
	if (comret == COMPLETE) {
		strcpy(typename, p->t_name);
		type = p->t_type;
	}
}

/*
 * Set binary transfer type.
 */
/*VARARGS*/
setbinary()
{

	call(settype, "type", "binary", 0);
}

/*
 * Set ascii transfer type.
 */
/*VARARGS*/
setascii()
{

	call(settype, "type", "ascii", 0);
}

/*
 * Set tenex transfer type.
 */
/*VARARGS*/
settenex()
{

	call(settype, "type", "tenex", 0);
}

/*
 * Set ebcdic transfer type.
 */
/*VARARGS*/
setebcdic()
{

	call(settype, "type", "ebcdic", 0);
}

/*
 * Set file transfer mode.
 */
setmode(argc, argv)
	char *argv[];
{

	printf("We only support %s mode, sorry.\n", modename);
}

/*
 * Set file transfer format.
 */
setform(argc, argv)
	char *argv[];
{

	printf("We only support %s format, sorry.\n", formname);
}

/*
 * Set file transfer structure.
 */
setstruct(argc, argv)
	char *argv[];
{

	printf("We only support %s structure, sorry.\n", structname);
}

put(argc, argv)
	int argc;
	char *argv[];
{
	char *cmd;

	if (argc == 2)
		argc++, argv[2] = argv[1];
	if (argc < 2) {
		strcat(line, " ");
		printf("(local-file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
usage:
		printf("%s local-file remote-file\n", argv[0]);
		return;
	}
	if (argc < 3) {
		strcat(line, " ");
		printf("(remote-file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3) 
		goto usage;
	if (!globulize(&argv[1]))
		return;
	cmd = (argv[0][0] == 'a') ? "APPE" : "STOR";
	sendrequest(cmd, argv[1], argv[2]);
}

/*
 * Send multiple files.
 */
mput(argc, argv)
	char *argv[];
{
	register int i;

	if (argc < 2) {
		strcat(line, " ");
		printf("(local-files) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s local-files\n", argv[0]);
		return;
	}
	for (i = 1; i < argc; i++) {
		register char **cpp, **gargs;

		if (!doglob) {
			if (confirm(argv[0], argv[i]))
				sendrequest("STOR", argv[i], argv[i]);
			continue;
		}
		gargs = glob(argv[i]);
		if (globerr != NULL) {
			printf("%s\n", globerr);
			if (gargs && globcnt)
				blkfree(gargs);
			continue;
		}
		for (cpp = gargs; cpp && *cpp != NULL; cpp++)
			if (confirm(argv[0], *cpp))
				sendrequest("STOR", *cpp, *cpp);
		if (gargs != NULL && globcnt)
			blkfree(gargs);
	}
}

/*
 * Receive one file.
 */
get(argc, argv)
	char *argv[];
{

	if (argc == 2)
		argc++, argv[2] = argv[1];
	if (argc < 2) {
		strcat(line, " ");
		printf("(remote-file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
usage:
		printf("%s remote-file [ local-file ]\n", argv[0]);
		return;
	}
	if (argc < 3) {
		strcat(line, " ");
		printf("(local-file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3) 
		goto usage;
	if (!globulize(&argv[2]))
		return;
	recvrequest("RETR", argv[2], argv[1], "w");
}

/*
 * Get multiple files.
 */
mget(argc, argv)
	char *argv[];
{
	char *cp;

	if (argc < 2) {
		strcat(line, " ");
		printf("(remote-files) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s remote-files\n", argv[0]);
		return;
	}
	while ((cp = remglob(argc, argv)) != NULL)
		if (confirm(argv[0], cp))
			recvrequest("RETR", cp, cp, "w");
}

char *
remglob(argc, argv)
	char *argv[];
{
	char temp[16];
	static char buf[MAXPATHLEN];
	static FILE *ftemp = NULL;
	static char **args;
	int oldverbose, oldhash;
	char *cp, *mode;

	if (!doglob) {
		if (args == NULL)
			args = argv;
		if ((cp = *++args) == NULL)
			args = NULL;
		return (cp);
	}
	if (ftemp == NULL) {
		strcpy(temp, "/tmp/ftpXXXXXX");
		mktemp(temp);
		oldverbose = verbose, verbose = 0;
		oldhash = hash, hash = 0;
		for (mode = "w"; *++argv != NULL; mode = "a")
			recvrequest ("NLST", temp, *argv, mode);
		verbose = oldverbose; hash = oldhash;
		ftemp = fopen(temp, "r");
		unlink(temp);
		if (ftemp == NULL) {
			printf("can't find list of remote files, oops\n");
			return (NULL);
		}
	}
	if (fgets(buf, sizeof (buf), ftemp) == NULL) {
		fclose(ftemp), ftemp = NULL;
		return (NULL);
	}
	if ((cp = strchr(buf, '\n')) != NULL)
		*cp = '\0';
	return (buf);
}

char *
onoff(bool)
	int bool;
{

	return (bool ? "on" : "off");
}

/*
 * Show status.
 */
status(argc, argv)
	char *argv[];
{

	if (cncted)
		printf("Connected to %s.\n", hostname);
	else
		printf("Not connected.\n");
	printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
		modename, typename, formname, structname);
	printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 
		onoff(verbose), onoff(bell), onoff(interactive),
		onoff(doglob));
	printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
		onoff(hash), onoff(sendport));
}

/*
 * Set beep on cmd completed mode.
 */
/*VARARGS*/
setbell()
{

	bell = !bell;
	printf("Bell mode %s.\n", onoff(bell));
}

/*
 * Turn on packet tracing.
 */
/*VARARGS*/
settrace()
{

	trace = !trace;
	printf("Packet tracing %s.\n", onoff(trace));
}

/*
 * Toggle hash mark printing during transfers.
 */
/*VARARGS*/
sethash()
{

	hash = !hash;
	printf("Hash mark printing %s", onoff(hash));
	if (hash)
		printf(" (%d bytes/hash mark)", BUFSIZ);
	printf(".\n");
}

/*
 * Turn on printing of server echo's.
 */
/*VARARGS*/
setverbose()
{

	verbose = !verbose;
	printf("Verbose mode %s.\n", onoff(verbose));
}

/*
 * Toggle PORT cmd use before each data connection.
 */
/*VARARGS*/
setport()
{

	sendport = !sendport;
	printf("Use of PORT cmds %s.\n", onoff(sendport));
}

/*
 * Turn on interactive prompting
 * during mget, mput, and mdelete.
 */
/*VARARGS*/
setprompt()
{

	interactive = !interactive;
	printf("Interactive mode %s.\n", onoff(interactive));
}

/*
 * Toggle metacharacter interpretation
 * on local file names.
 */
/*VARARGS*/
setglob()
{
	
	doglob = !doglob;
	printf("Globbing %s.\n", onoff(doglob));
}

/*
 * Set debugging mode on/off and/or
 * set level of debugging.
 */
/*VARARGS*/
setdebug(argc, argv)
	char *argv[];
{
	int val;

	if (argc > 1) {
		val = atoi(argv[1]);
		if (val < 0) {
			printf("%s: bad debugging value.\n", argv[1]);
			return;
		}
	} else
		val = !debug;
	debug = val;
	if (debug)
		options |= SO_DEBUG;
	else
		options &= ~SO_DEBUG;
	printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
}

/*
 * Set current working directory
 * on remote machine.
 */
cd(argc, argv)
	char *argv[];
{

	if (argc < 2) {
		strcat(line, " ");
		printf("(remote-directory) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s remote-directory\n", argv[0]);
		return;
	}
	(void) command("CWD %s", argv[1]);
}

/*
 * Set current working directory
 * on local machine.
 */
lcd(argc, argv)
	char *argv[];
{
	char buf[MAXPATHLEN];

	if (argc < 2)
		argc++, argv[1] = home;
	if (argc != 2) {
		printf("%s local-directory\n", argv[0]);
		return;
	}
	if (!globulize(&argv[1]))
		return;
	if (chdir(argv[1]) < 0) {
		perror(argv[1]);
		return;
	}
	printf("Lo (   (  cal directory now %s\n", getcwd(buf, sizeof (buf)));
}

/*
 * Delete a single file.
 */
delete(argc, argv)
	char *argv[];
{

	if (argc < 2) {
		strcat(line, " ");
		printf("(remote-file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s remote-file\n", argv[0]);
		return;
	}
	(void) command("DELE %s", argv[1]);
}

/*
 * Delete multiple files.
 */
mdelete(argc, argv)
	char *argv[];
{
	char *cp;

	if (argc < 2) {
		strcat(line, " ");
		printf("(remote-files) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s remote-files\n", argv[0]);
		return;
	}
	while ((cp = remglob(argc, argv)) != NULL)
		if (confirm(argv[0], cp))
			(void) command("DELE %s", cp);
}

/*
 * Rename a remote file.
 */
renamefile(argc, argv)
	char *argv[];
{

	if (argc < 2) {
		strcat(line, " ");
		printf("(from-name) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
usage:
		printf("%s from-name to-name\n", argv[0]);
		return;
	}
	if (argc < 3) {
		strcat(line, " ");
		printf("(to-name) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3) 
		goto usage;
	if (command("RNFR %s", argv[1]) == CONTINUE)
		(void) command("RNTO %s", argv[2]);
}

/*
 * Get a directory listing
 * of remote files.
 */
ls(argc, argv)
	char *argv[];
{
	char *cmd;

	if (argc < 2)
		argc++, argv[1] = NULL;
	if (argc < 3)
		argc++, argv[2] = "-";
	if (argc > 3) {
		printf("usage: %s remote-directory local-file\n", argv[0]);
		return;
	}
	cmd = argv[0][0] == 'l' ? "NLST" : "LIST";
	if (strcmp(argv[2], "-") && !globulize(&argv[2]))
		return;
	recvrequest(cmd, argv[2], argv[1], "w");
}

/*
 * Get a directory listing
 * of multiple remote files.
 */
mls(argc, argv)
	char *argv[];
{
	char *cmd, *mode, *cp, *dest;

	if (argc < 2) {
		strcat(line, " ");
		printf("(remote-files) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3) {
		strcat(line, " ");
		printf("(local-file) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 3) {
		printf("%s remote-files local-file\n", argv[0]);
		return;
	}
	dest = argv[argc - 1];
	argv[argc - 1] = NULL;
	if (strcmp(dest, "-"))
		if (!globulize(&dest) || !confirm("local-file", dest))
			return;
	cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
	for (mode = "w"; cp = remglob(argc, argv); mode = "a")
		if (confirm(argv[0], cp))
			recvrequest(cmd, dest, cp, mode);
}

/*
 * Do a shell escape
 */
shell(argc, argv)
	char *argv[];
{
	int pid, status, (*old1)(), (*old2)();
	char shellnam[40], *shell, *namep;
	char **cpp, **gargs;

	old1 = signal (SIGINT, SIG_IGN);
	old2 = signal (SIGQUIT, SIG_IGN);
	if ((pid = fork()) == 0) {
		for (pid = 3; pid < 20; pid++)
			close(pid);
		signal(SIGINT, SIG_DFL);
		signal(SIGQUIT, SIG_DFL);
		if (argc <= 1) {
			shell = getenv("SHELL");
			if (shell == NULL)
				shell = "/bin/sh";
			namep = strrchr(shell,'/');
			if (namep == NULL)
				namep = shell;
			strcpy(shellnam,"-");
			strcat(shellnam, ++namep);
			if (strcmp(namep, "sh") != 0)
				shellnam[0] = '+';
			if (debug) {
				printf ("%s\n", shell);
				fflush (stdout);
			}
			execl(shell, shellnam, 0);
			perror(shell);
			exit(1);
		}
		cpp = &argv[1];
		if (argc > 2) {
			if ((gargs = glob(cpp)) != NULL)
				cpp = gargs;
			if (globerr != NULL) {
				printf("%s\n", globerr);
				exit(1);
			}
		}
		if (debug) {
			register char **zip = cpp;

			printf("%s", *zip);
			while (*++zip != NULL)
				printf(" %s", *zip);
			printf("\n");
			fflush(stdout);
		}
		execvp(argv[1], cpp);
		perror(argv[1]);
		exit(1);
	}
	if (pid > 0)
		while (wait(&status) != pid)
			;
	signal(SIGINT, old1);
	signal(SIGQUIT, old2);
	if (pid == -1)
		perror("Try again later");
	return (0);
}

/*
 * Send new user information (re-login)
 */
user(argc, argv)
	int argc;
	char **argv;
{
	char acct[80], *getpass();
	int n;

	if (argc < 2) {
		strcat(line, " ");
		printf("(username) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc > 4) {
		printf("usage: %s username [password] [account]\n", argv[0]);
		return (0);
	}
	n = command("USER %s", argv[1]);
	if (n == CONTINUE) {
		if (argc < 3 )
			argv[2] = getpass("Password: "), argc++;
		n = command("PASS %s", argv[2]);
	}
	if (n == CONTINUE) {
		if (argc < 4) {
			printf("Account: "); (void) fflush(stdout);
			(void) fgets(acct, sizeof(acct) - 1, stdin);
			acct[strlen(acct) - 1] = '\0';
			argv[3] = acct; argc++;
		}
		n = command("ACCT %s", acct);
	}
	if (n != COMPLETE) {
		fprintf(stderr, "Login failed.\n");
		return (0);
	}
	return (1);
}

/*
 * Print working directory.
 */
/*VARARGS*/
pwd()
{

	(void) command("XPWD");
}

/*
 * Make a directory.
 */
makedir(argc, argv)
	char *argv[];
{

	if (argc < 2) {
		strcat(line, " ");
		printf("(directory-name) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s directory-name\n", argv[0]);
		return;
	}
	(void) command("XMKD %s", argv[1]);
}

/*
 * Remove a directory.
 */
removedir(argc, argv)
	char *argv[];
{

	if (argc < 2) {
		strcat(line, " ");
		printf("(directory-name) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("%s directory-name\n", argv[0]);
		return;
	}
	(void) command("XRMD %s", argv[1]);
}

/*
 * Send a line, verbatim, to the remote machine.
 */
quote(argc, argv)
	char *argv[];
{
	int i;
	char buf[BUFSIZ];

	if (argc < 2) {
		strcat(line, " ");
		printf("(command line to send) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc < 2) {
		printf("usage: %s line-to-send\n", argv[0]);
		return;
	}
	strcpy(buf, argv[1]);
	for (i = 2; i < argc; i++) {
		strcat(buf, " ");
		strcat(buf, argv[i]);
	}
	(void) command(buf);
}

/*
 * Ask the other side for help.
 */
rmthelp(argc, argv)
	char *argv[];
{
	int oldverbose = verbose;

	verbose = 1;
	(void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
	verbose = oldverbose;
}

/*
 * Terminate session and exit.
 */
/*VARARGS*/
quit()
{

	disconnect();
	exit(0);
}

/*
 * Terminate session, but don't exit.
 */
disconnect()
{
	extern FILE *cout;
	extern int data;

	if (!cncted)
		return;
	(void) command("QUIT");
	(void) fclose(cout);
	cout = NULL;
	cncted = 0;
	data = -1;
}

confirm(cmd, file)
	char *cmd, *file;
{
	char line[BUFSIZ];

	if (!interactive)
		return (1);
	printf("%s %s? ", cmd, file);
	fflush(stdout);
	gets(line);
	return (*line != 'n' && *line != 'N');
}

fatal(msg)
	char *msg;
{

	fprintf(stderr, "ftp: %s\n");
	exit(1);
}

/*
 * Glob a local file name specification with
 * the expectation of a single return value.
 * Can't control multiple values being expanded
 * from the expression, we return only the first.
 */
globulize(cpp)
	char **cpp;
{
	char **globbed;

	if (!doglob)
		return (1);
	globbed = glob(*cpp);
	if (globerr != NULL) {
		printf("%s: %s\n", *cpp, globerr);
		if (globbed)
			blkfree(globbed);
		return (0);
	}
	if (globbed) {
		*cpp = *globbed++;
		/* don't waste too much memory */
		if (*globbed)
			blkfree(globbed);
	}
	return (1);
}
me, structname);
	printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 
		onoff(verbose), onoff(bell), onoff(interactive),
		onoff(doglob));
	printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
		onoff(hash), onoff(sendport));
}

/*
 * Set beep on cmd completed mode.
 */
/*VARARGS*/
setbell()
{

	bell = !bell;
	printf("Bell mode %s.\n", onoff(bell));
}

/*
 * Turn on packet tracing.
 */
/*VARARGS*/
settrace()
{

	traunix/users/ftp/cmdtab.c                                                                                444     322     145        11223  3621344632  10461                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)cmdtab.c	5.0 (CMC) 9/10/84";
#endif

#include "ftp_var.h"

/*
 * User FTP -- Command Tables.
 */
int	setascii(), setbell(), setbinary(), setdebug(), setform();
int	setglob(), sethash(), setmode(), setpeer(), setport();
int	setprompt(), setstruct();
int	settenex(), settrace(), settype(), setverbose();
int	disconnect();
int	cd(), lcd(), delete(), mdelete(), user();
int	ls(), mls(), get(), mget(), help(), append(), put(), mput();
int	quit(), renamefile(), status();
int	quote(), rmthelp(), shell();
int	pwd(), makedir(), removedir();

char	appendhelp[] =	"append to a file";
char	asciihelp[] =	"set ascii transfer type";
char	beephelp[] =	"beep when command completed";
char	binaryhelp[] =	"set binary transfer type";
char	cdhelp[] =	"change remote working directory";
char	cncthelp[] =	"connect to remote tftp";
char	deletehelp[] =	"delete remote file";
char	debughelp[] =	"toggle/set debugging mode";
char	dirhelp[] =	"list contents of remote directory";
char	dscnhlp[] =	"terminate ftp session";
char	formhelp[] =	"set file transfer format";
char	globhelp[] =	"toggle metacharacter expansion of local file names";
char	hashhelp[] =	"toggle printing `#' for each buffer transferred";
char	helphelp[] =	"print local help information";
char	lcdhelp[] =	"change local working directory";
char	lshelp[] =	"nlist contents of remote directory";
char	mdelhelp[] =	"delete multiple files";
char	mdirhelp[] =	"list contents of multiple remote directories";
char	mgethelp[] =	"get multiple files";
char	mkdirhelp[] =	"make directory on the remote machine";
char	mlshelp[] =	"nlist contents of multiple remote directories";
char	modehelp[] =	"set file transfer mode";
char	mputhelp[] =	"send multiple files";
char	 (   (  porthelp[] =	"toggle use of PORT cmd for each data cnction";
char	prompthelp[] =	"force interactive prompting on multiple commands";
char	pwdhelp[] =	"print working directory on remote machine";
char	quithelp[] =	"terminate ftp session and exit";
char	quotehelp[] =	"send arbitrary ftp command";
char	receivehelp[] =	"receive file";
char	remotehelp[] =	"get help from remote server";
char	renamehelp[] =	"rename file";
char	rmdirhelp[] =	"remove directory on the remote machine";
char	sendhelp[] =	"send one file";
char	shellhelp[] =	"escape to the shell";
char	statushelp[] =	"show current status";
char	structhelp[] =	"set file transfer structure";
char	tenexhelp[] =	"set tenex file transfer type";
char	tracehelp[] =	"toggle packet tracing";
char	typehelp[] =	"set file transfer type";
char	userhelp[] =	"send new user information";
char	vrbshelp[] =	"toggle verbose mode";

struct cmd cmdtab[] = {
	{ "!",		shellhelp,	0,	0,	shell },
	{ "append",	appendhelp,	1,	1,	put },
	{ "ascii",	asciihelp,	0,	1,	setascii },
	{ "bell",	beephelp,	0,	0,	setbell },
	{ "binary",	binaryhelp,	0,	1,	setbinary },
	{ "bye",	quithelp,	0,	0,	quit },
	{ "cd",		cdhelp,		0,	1,	cd },
	{ "close",	dscnhlp,	0,	1,	disconnect },
	{ "connect",	cncthelp,	0,	0,	setpeer },
	{ "delete",	deletehelp,	0,	1,	delete },
	{ "debug",	debughelp,	0,	0,	setdebug },
	{ "dir",	dirhelp,	1,	1,	ls },
	{ "form",	formhelp,	0,	1,	setform },
	{ "get",	receivehelp,	1,	1,	get },
	{ "glob",	globhelp,	0,	0,	setglob },
	{ "hash",	hashhelp,	0,	0,	sethash },
	{ "help",	helphelp,	0,	0,	help },
	{ "lcd",	lcdhelp,	0,	0,	lcd },
	{ "ls",		lshelp,		1,	1,	ls },
	{ "mdelete",	mdelhelp,	1,	1,	mdelete },
	{ "mdir",	mdirhelp,	1,	1,	mls },
	{ "mget",	mgethelp,	1,	1,	mget },
	{ "mkdir",	mkdirhelp,	0,	1,	makedir },
	{ "mls",	mlshelp,	1,	1,	mls },
	{ "mode",	modehelp,	0,	1,	setmode },
	{ "mput",	mputhelp,	1,	1,	mput },
	{ "open",	cncthelp,	0,	0,	setpeer },
	{ "prompt",	prompthelp,	0,	0,	setprompt },
	{ "sendport",	porthelp,	0,	0,	setport },
	{ "put",	sendhelp,	1,	1,	put },
	{ "pwd",	pwdhelp,	0,	1,	pwd },
	{ "quit",	quithelp,	0,	0,	quit },
	{ "quote",	quotehelp,	1,	1,	quote },
	{ "recv",	receivehelp,	1,	1,	get },
	{ "remotehelp",	remotehelp,	0,	1,	rmthelp },
	{ "rename",	renamehelp,	0,	1,	renamefile },
	{ "rmdir",	rmdirhelp,	0,	1,	removedir },
	{ "send",	sendhelp,	1,	1,	put },
	{ "status",	statushelp,	0,	0,	status },
	{ "struct",	structhelp,	0,	1,	setstruct },
	{ "tenex",	tenexhelp,	0,	1,	settenex },
	{ "trace",	tracehelp,	0,	0,	settrace },
	{ "type",	typehelp,	0,	1,	settype },
	{ "user",	userhelp,	0,	1,	user },
	{ "verbose",	vrbshelp,	0,	0,	setverbose },
	{ "?",		helphelp,	0,	0,	help },
	{ 0 },
};

int	NCMDS = sizeof (cmdtab) / sizeof (cmdtab[0]);
ar **cpp, **gargs;

	old1 = signal (SIGINT, SIG_IGN);
	old2 = signal (SIGQUIT, SIG_IGN);
	if ((pid = fork()) == 0) {
		for (pid = 3; pid < 20; pid++)
			close(pid);
		signal(SIGINT, SIG_DFL);
		signal(SIGQUIT, SIG_DFL);
		if (argc <= 1) {
			shell = getenv("SHELL");
			if (shell == NULL)
				shell = "/bin/sh";
			namep = strrchr(shell,'/');
			if (namep == NULL)
unix/users/ftp/ftp.c                                                                                   444     322     145        27017  3621344633  10031                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)ftp.c	5.0 (CMC) 9/10/84";
#endif

/*
 * Based on 4.2 version of ftp.
 *
 * September 5, 1984 - Modified to use System 5 type of non-blocking I/O.
 *			Deb Brown, CMC
 * September, 1984   - Completed conversion to Sys V
 *			John Mullen
 */

#include <CMC/sysdep.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <CMC/socket.h>

#include <CMC/in.h>
#include <CMC/ftp.h>

#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <CMC/errno.h>
#include <CMC/netdb.h>

#include "ftp_var.h"

struct	sockaddr_in hisctladdr;
struct	sockaddr_in data_addr;
int	data = -1;
int	cncted;
struct	sockaddr_in myctladdr;

FILE	*cin, *cout;
FILE	*dataconn();

struct hostent *
hookup(host, port)
	char *host;
	int port;
{
	register struct hostent *hp;
	int s, len;

	memset((char *)&hisctladdr, '\0', sizeof (hisctladdr));
	hp = gethostbyname(host);
	if (hp == NULL) {
		static struct hostent def;
		static struct in_addr defaddr;
		static char namebuf[128];
		int inet_addr();

		defaddr.s_addr = inet_addr(host);
		if (defaddr.s_addr == -1) {
			fprintf(stderr, "%s: Unknown host.\n", host);
			return (0);
		}
		strcpy(namebuf, host);
		def.h_name = namebuf;
		hostname = namebuf;
		def.h_addr = (char *)&defaddr;
		def.h_length = sizeof (struct in_addr);
		def.h_addrtype = AF_INET;
		def.h_aliases = 0;
		hp = &def;
	}
	hostname = hp->h_name;
	hisctladdr.sin_family = hp->h_addrtype;
	s = socket(hp->h_addrtype, SOCK_STREAM, 0);
	if (s < 0) {
		perror("ftp: socket");
		return (0);
	}
	if (bind(s, (char *)&hisctladdr, sizeof (hisctladdr)) < 0) {
		perror("ftp: bind");
		goto bad;
	}
	memcpy((char *)&hisctladdr.sin_addr, hp->h_addr, hp->h_length);
	hisctladdr.sin_port = port;
	if (connect(s, (char *)&hisctladdr, sizeof (hisctladdr)) < 0) {
		perror("ftp: connect");
		goto bad;
	}
	len = sizeof (myctladdr);
	if (getsockname(s, (char *)&myctladdr, &len) < 0) {
		perror("ftp: getsockname");
		goto bad;
	}
	cin = fdopen(s, "r");
	cout = fdopen(s, "w");
	if (cin == NULL || cout == NULL) {
		fprintf(stderr, "ftp: fdopen failed.\n");
		if (cin)
			fclose(cin);
		if (cout)
			fclose(cout);
		goto bad;
	}
	if (verbose)
		printf("Connected to %s.\n", hp->h_name);
	(void) getreply(0); 		/* read startup message from server */
	return (hp);
bad:
	close(s);
	return ((struct hostent *)0);
}

login(hp)
	struct hostent *hp;
{
	char acct[80];
	char *user, *pass;
	int n;

	user = pass = 0;
	ruserpass(hp->h_name, &user, &pass);
	n = command("USER %s", user);
	if (n == CONTINUE)
		n = command("PASS %s", pass);
	if (n == CONTINUE) {
		printf("Account: "); (void) fflush(stdout);
		(void) fgets(acct, sizeof(acct) - 1, stdin);
		acct[strlen(acct) - 1] = '\0';
		n = command("ACCT %s", acct);
	}
	if (n != COMPLETE) {
		fprintf(stderr, "Login failed.\n");
		return (0);
	}
	return (1);
}

/*VARARGS 1*/
command(fmt, args)
	char *fmt;
{

	if (debug) {
		printf("---> ");
		_doprnt(fmt, &args, stdout);
		printf("\n");
		(void) fflush(stdout);
	}
	if (cout == NULL) {
		perror ("No control connection for command");
		return (0);
	}
	_doprnt(fmt, &args, cout);
	fprintf(cout, "\r\n");
	(void) fflush(cout);
	return (getreply(!strcmp(fmt, "QUIT")));
}

#include <ctype.h>

getreply(expecteof)
	int expecteof;
{
	register int c, n;
	register int code, dig;
	int originalcode = 0, continuation = 0;

	for (;;) {
		dig = n = code = 0;
		while ((c = getc(cin)) != '\n') {
			dig++;
			if (c == EOF) {
				if (expecteof)
					return (0);
				lostpeer();
				exit(1);
			}
			if (verbose && c != '\r' ||
			    (n == '5' && dig > 4))
				putchar(c);
			if (dig < 4 && isdigit(c))
				code = code * 10 + (c - '0');
			if (dig == 4 && c == '-')
				continuation++;
			if (n == 0)
				n = c;
		}
		if (verbose || n == '5') {
			putchar(c);
			(void) fflush (stdout);
		}
		if (continuation && code != originalcode) {
			if (originalcode == 0)
				originalcode = code;
			continue;
		}
		if (expecteof || empty(cin))
			return (n - '0');
	}
}

empty(f)
	FILE *f;
{
	register int flags, fn;
	char c;

	if (f->_cnt > 0)
		return (0);

	fn = fileno (f);
	flags = fcntl (fn, F_GETFL, 0);
	fcntl (fn, F_SETFL, flags|O_NDELAY);		/* non-blocking i/o */
	if (read (fn, &c, 1) > 0) {
		ungetc (c, f);
		fcntl (fn, F_SETFL, flags);
		return (0);
	}
	else {
		fcntl (fn, F_SETFL, flags);
		return (1);
	}
}

jmp_buf	sendabort;

abortsend()
{

	longjmp(sendabort, 1);
}

sendrequest(cmd, local, remote)
	char *cmd, *local, *remote;
{
	FILE *fin, *dout, *popen();
	int (*closefunc)(), pclose(), fclose(), (*oldintr)();
	char buf[BUFSIZ];
	long bytes = 0, hashbytes = sizeof (buf);
	register int c, d;
	struct stat st;
	long start, stop;

	closefunc = NULL;
	if (setjmp(sendabort))
		goto bad;
	oldintr = signal(SIGINT, abortsend);
	if (strcmp(local, "-") == 0)
		fin = stdin;
	else if (*local == '|') {
		fin = popen(local + 1, "r");
		if (fin == NULL) {
			perror(local + 1);
			goto bad;
		}
		closefunc = pclose;
	} else {
		fin = fopen(local, "r");
		if (fin == NULL) {
			perror(local);
			goto bad;
		}
		closefunc = fclose;
		if (fstat(fileno(fin), &st) < 0 ||
		    (st.st_mode&S_IFMT) != S_IFREG) {
			fprintf(stderr, "%s: not a plain file.", local);
			goto bad;
		}
	}
	if (initconn())
		goto bad;
	if (remote) {
		if (command("%s %s", cmd, remote) != PRELIM)
			goto bad;
	} else
		if (command("%s", cmd) != PRELIM)
			goto bad;
	dout = dataconn("w");
	if (dout == NULL)
		goto bad;
	time (&start);
	switch (type) {

	case TYPE_I:
	case TYPE_L:
		errno = d = 0;
		while ((c = read(fileno (fin), buf, sizeof (buf))) > 0) {
			if ((d = write(fileno (dout), buf, c)) < 0)
				break;
			bytes += c;
			if (hash) {
				putchar('#');
				fflush(stdout);
			}
		}
		if (hash && bytes > 0) {
			putchar('\n');
			fflush(stdout);
		}
		if (c < 0)
			perror(local);
		if (d < 0)
			perror("netout");
		break;

	case TYPE_A:
		while ((c = getc(fin)) != EOF) {
			if (c == '\n') {
				while (hash && (bytes >= hashbytes)) {
					putchar('#');
					fflush(stdout);
					hashbytes += sizeof (buf);
				}
				if (ferror(dout))
					break;
				putc('\r', dout);
				bytes++;
			}
			putc(c, dout);
			bytes++;
			if (c == '\r') {
				putc('\0', dout);
				bytes++;
			}
		}
		if (hash) {
			if (bytes < hashbytes)
				putchar('#');
			putchar('\n');
			fflush(stdout);
	 (   (  	}
		if (ferror(fin))
			perror(local);
		if (ferror(dout))
			perror("netout");
		break;
	}
	time (&stop);
	if (closefunc != NULL)
		(*closefunc)(fin);
	(void) fclose(dout);
	(void) getreply(0);
done:
	signal(SIGINT, oldintr);
	if (bytes > 0 && verbose)
		ptransfer("sent", bytes, start, stop);
	return;
bad:
	if (data >= 0)
		(void) close(data), data = -1;
	if (closefunc != NULL && fin != NULL)
		(*closefunc)(fin);
	goto done;
}

jmp_buf	recvabort;

abortrecv()
{

	longjmp(recvabort, 1);
}

recvrequest(cmd, local, remote, mode)
	char *cmd, *local, *remote, *mode;
{
	FILE *fout, *din, *popen();
	int (*closefunc)(), pclose(), fclose(), (*oldintr)();
	char *strrchr();
	char buf[BUFSIZ];
	long bytes = 0, hashbytes = sizeof (buf);
	register int c, d;
	long start, stop;
	int created = 0;
	extern errno;

	closefunc = NULL;
	if (setjmp(recvabort))
		goto bad;
	oldintr = signal(SIGINT, abortrecv);
	if (strcmp(local, "-") && *local != '|')
		if (access(local, 2) < 0) {
			char *dir = strrchr(local, '/');

			created = errno == ENOENT;
			if (dir != NULL)
				*dir = 0;
			if (access(dir ? local : ".", 2) < 0) {
				perror(local);
				if (dir != NULL)
					*dir = '/';
				goto bad;
			}
			if (dir != NULL)
				*dir = '/';
		}
	if (initconn())
		goto bad;
	if (remote) {
		if (command("%s %s", cmd, remote) != PRELIM)
			goto bad;
	} else
		if (command("%s", cmd) != PRELIM)
			goto bad;
	if (strcmp(local, "-") == 0)
		fout = stdout;
	else if (*local == '|') {
		fout = popen(local + 1, "w");
		closefunc = pclose;
	} else {
		fout = fopen(local, mode);
		closefunc = fclose;
	}
	if (fout == NULL) {
		perror(local + 1);
		goto bad;
	}
	if ( created )
		chown ( local, getuid(), getgid() );
	din = dataconn("r");
	if (din == NULL)
		goto bad;
	time (&start);
	switch (type) {

	case TYPE_I:
	case TYPE_L:
		errno = d = 0;
		while ((c = read(fileno(din), buf, sizeof (buf))) > 0) {
			if ((d = write(fileno(fout), buf, c)) < 0)
				break;
			bytes += c;
			if (hash) {
				putchar('#');
				fflush(stdout);
			}
		}
		if (hash && bytes > 0) {
			putchar('\n');
			fflush(stdout);
		}
		if (c < 0)
			perror("netin");
		if (d < 0)
			perror(local);
		break;

	case TYPE_A:
		while ((c = getc(din)) != EOF) {
			if (c == '\r') {
				while (hash && (bytes >= hashbytes)) {
					putchar('#');
					fflush(stdout);
					hashbytes += sizeof (buf);
				}
				bytes++;
				if ((c = getc(din)) != '\n') {
					if (ferror (fout))
						break;
					putc ('\r', fout);
				}
				if (c == '\0') {
					bytes++;
					continue;
				}
			}
			putc (c, fout);
			bytes++;
		}
		if (hash) {
			if (bytes < hashbytes)
				putchar('#');
			putchar('\n');
			fflush(stdout);
		}
		if (ferror (din))
			perror ("netin");
		if (ferror (fout))
			perror (local);
		break;
	}
	time (&stop);
	(void) fclose(din);
	if (closefunc != NULL)
		(*closefunc)(fout);
	(void) getreply(0);
done:
	signal(SIGINT, oldintr);
	if (bytes > 0 && verbose)
		ptransfer("received", bytes, start, stop);
	return;
bad:
	if (data >= 0)
		(void) close(data), data = -1;
	if (closefunc != NULL && fout != NULL)
		(*closefunc)(fout);
	goto done;
}

/*
 * Need to start a listen on the data channel
 * before we send the command, otherwise the
 * server's connect may fail.
 */
static int sendport = -1;

initconn()
{
	register char *p, *a;
	int result, len;

noport:
	data_addr = myctladdr;
	if (sendport)
		data_addr.sin_port = 0;	/* let system pick one */ 
	if (data != -1)
		(void) close (data);
	data = socket(AF_INET, SOCK_STREAM, 0);
	if (data < 0) {
		perror("ftp: socket");
		return (1);
	}
	if (!sendport)
		if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) {
			perror("ftp: setsockopt (resuse address)");
			goto bad;
		}
	if (bind(data, (char *)&data_addr, sizeof (data_addr)) < 0) {
		perror("ftp: bind");
		goto bad;
	}
	if (options & SO_DEBUG &&
	    setsockopt(data, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
		perror("ftp: setsockopt (ignored)");
	len = sizeof (data_addr);
	if (getsockname(data, (char *)&data_addr, &len) < 0) {
		perror("ftp: getsockname");
		goto bad;
	}
	if (listen(data, 1) < 0) {
		perror("ftp: listen");
		goto bad;
	}
	if (sendport) {
		a = (char *)&data_addr.sin_addr;
		p = (char *)&data_addr.sin_port;
#define	UC(b)	(((int)b)&0xff)
		result =
		    command("PORT %d,%d,%d,%d,%d,%d",
		      UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
		      UC(p[0]), UC(p[1]));
		if (result == ERROR && sendport == -1) {
			sendport = 0;
			goto noport;
		}
		return (result != COMPLETE);
	}
	return (0);
bad:
	(void) close(data), data = -1;
	return (1);
}

FILE *
dataconn(mode)
	char *mode;
{
	struct sockaddr_in from;
	int s, fromlen = sizeof (from);

	s = accept(data, &from, &fromlen, 0);
	if (s < 0) {
		perror("ftp: accept");
		(void) close(data), data = -1;
		return (NULL);
	}
	(void) close(data);
	data = s;
	return (fdopen(data, mode));
}

ptransfer(direction, bytes, t0, t1)
	char *direction;
	long bytes;
	long t0, t1;
{
	long sec;
	float bs;

	sec = t1 - t0;
#define	nz(x)	((x) == 0 ? 1 : (x))
	bs = ((bytes * NBBY) / (float) nz(sec)) / NBBY;
	printf("%ld bytes %s in %d seconds (%.2g Kbytes/s)\n",
		bytes, direction, sec, bs / 1024.);
}
cal, "-") == 0)
		fin = stdin;
	else if (*local == '|') {
		fin = popen(local + 1, "r");
		if (fin == NULL) {
			perror(local + 1);
			goto bad;
		}
		closefunc = pclose;
	} else {
		fin = fopen(local, "r");
		if (fin == NULL) {
			perror(local);
			goto bad;
		}
		closefunc = fclose;
		if (fstat(fileno(fin), &st) < 0 ||
		    (st.st_mode&S_IFMT) != S_IFREG) {
			fprintf(stderr, "%s: not a plain file.", local);
			goto bad;
		}
	}
	if (initconn())
		goto bad;
	if (remote) {
		if (command("%s unix/users/ftp/ftp_var.h                                                                               444     322     145         4542  3621344634  10665                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*	ftp_var.h	5.0	9/10/84	*/

/*
 * FTP global variables.
 */

/*
 * Options and other state info.
 */
int	trace;			/* trace packets exchanged */
int	hash;			/* print # for each buffer transferred */
int	sendport;		/* use PORT cmd for each data connection */
int	verbose;		/* print messages coming back from server */
int	cncted;			/* connected to server */
int	fromatty;		/* input is from a terminal */
int	interactive;		/* interactively prompt on m* cmds */
int	debug;			/* debugging level */
int	bell;			/* ring bell on cmd completion */
int	doglob;			/* glob local file names */
int	autologin;		/* establish user account on connection */

char	typename[32];		/* name of file transfer type */
int	type;			/* file transfer type */
char	structname[32];		/* name of file transfer structure */
int	stru;			/* file transfer structure */
char	formname[32];		/* name of file transfer format */
int	form;			/* file transfer format */
char	modename[32];		/* name of file transfer mode */
int	mode;			/* file transfer mode */
char	bytename[32];		/* local byte size in ascii */
int	bytesize;		/* local byte size in binary */

char	*hostname;		/* name of host connected to */

struct	servent *servp;		/* service spec for tcp/ftp */

#include <setjmp.h>
jmp_buf	toplevel;		/* non-local goto stuff for cmd scanner */

char	line[200];		/* input line buffer */
char	*stringbase;		/* current scan point in line buffer */
char	argbuf[200];		/* argument storage buffer */
char	*argbase;		/* current storage point in arg buffer */
int	margc;			/* count of arguments on input line */
char	*margv[20];		/* args parsed from input line */

int	options;		/* used during socket creation */

int	globcnt;		/* # names a string expanded to */

/*
 * Format of command table.
 */
struct cmd {
	char	*c_name;	/* name of command */
	char	*c_help;	/* help string */
	char	c_bell;		/* give bell when command completes */
	char	c_conn;		/* must be connected to use command */
	int	(*c_handler)();	/* function to call */
};

extern	char *tail();
extern	char *strchr();
extern	char *strrchr();
extern	char *remglob();
extern	int errno;

					if (ferror (fout))
						break;
					putc ('\r', fout);
				}
				if (c == '\0') {
					bytes++;
					continue;
				}
			}
			putc (c, fout);
			bytes++unix/users/ftp/getpass.c                                                                               444     322     145         2230  3621344634  10655                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)getpass.c	5.0 (CMC) 9/10/84";
#endif

#include <CMC/sysdep.h>
#include <stdio.h>
#include <signal.h>
#include <termio.h>

char *
getpass(prompt)
char *prompt;
{
	struct termio t1, t2;
	int flags;
	register char *p;
	register c;
	FILE *fi;
	static char pbuf[9];
	int (*signal())();
	int (*sig)();

	if ((fi = fdopen(open("/dev/tty", 2), "r")) == NULL)
		fi = stdin;
	else
		setbuf(fi, (char *)NULL);
	sig = signal(SIGINT, SIG_IGN);
	ioctl(fileno(fi), TCGETA, &t1);
	t2 = t1;
	t1.c_lflag &= ~(ECHO|ECHO|ECHONL);
	ioctl(fileno(fi), TCSETAF, &t1);
	fprintf(stderr, "%s", prompt); fflush(stderr);
	for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
		if (p < &pbuf[8])
			*p++ = c;
	}
	*p = (   (   '\0';
	fprintf(stderr, "\n"); fflush(stderr);
	ioctl(fileno(fi), TCSETAF, &t2);
	signal(SIGINT, sig);
	if (fi != stdin)
		fclose(fi);
	return(pbuf);
}
ation Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)getpass.c	5.0 (CMC) 9/10/84";
#endif

#include <CMC/sysdep.h>
#include <stdio.h>
#include <signal.h>
#include <termio.h>

char *
getpass(prompt)
char *prompt;
{
	struct tunix/users/ftp/glob.c                                                                                  444     322     145        22756  3621344635  10172                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)glob.c	5.0 (CMC) 09/28/84";
#endif

/*
 * C-shell glob for random programs.
 */

#include <CMC/types.h>
#include <CMC/longnames.h>
#include <CMC/param.h>
#include <sys/stat.h>
#include <CMC/dir.h>

#include <stdio.h>
#include <CMC/errno.h>
#include <pwd.h>

#define	QUOTE 0200
#define	TRIM 0177
#define	eq(a,b)		(strcmp(a, b)==0)
#define	GAVSIZ		(NCARGS/6)
#define	isdir(d)	((d.st_mode & S_IFMT) == S_IFDIR)

static	char **gargv;		/* Pointer to the (stack) arglist */
static	short gargc;		/* Number args in gargv */
static	short gnleft;
static	short gflag;
static	int tglob();
char	**glob();
char	*globerr;
char	*home;
struct	passwd *getpwnam();
extern	int errno;
static	char *strspl(), **copyblk(), *strend();
char	*malloc(), *strcpy(), *strcat();

static	int globcnt;

char	*globchars = "`{[*?";

static	char *gpath, *gpathp, *lastgpathp;
static	int globbed;
static	char *entp;
static	char **sortbas;

char **
glob(v)
	register char *v;
{
	char agpath[BUFSIZ];
	char *agargv[GAVSIZ];
	char *vv[2];
	vv[0] = v;
	vv[1] = 0;
	gflag = 0;
	rscan(vv, tglob);
	if (gflag == 0)
		return (copyblk(vv));

	globerr = 0;
	gpath = agpath; gpathp = gpath; *gpathp = 0;
	lastgpathp = &gpath[sizeof agpath - 2];
	ginit(agargv); globcnt = 0;
	collect(v);
	if (globcnt == 0 && (gflag&1)) {
		blkfree(gargv), gargv = 0;
		return (0);
	} else
		return (gargv = copyblk(gargv));
}

static
ginit(agargv)
	char **agargv;
{

	agargv[0] = 0; gargv = agargv; sortbas = agargv; gargc = 0;
	gnleft = NCARGS - 4;
}

static
collect(as)
	register char *as;
{
	if (eq(as, "{") || eq(as, "{}")) {
		Gcat(as, "");
		sort();
	} else
		acollect(as);
}

static
acollect(as)
	register char *as;
{
	register int ogargc = gargc;

	gpathp = gpath; *gpathp = 0; globbed = 0;
	expand(as);
	if (gargc != ogargc)
		sort();
}

static
sort()
{
	register char **p1, **p2, *c;
	char **Gvp = &gargv[gargc];

	p1 = sortbas;
	while (p1 < Gvp-1) {
		p2 = p1;
		while (++p2 < Gvp)
			if (strcmp(*p1, *p2) > 0)
				c = *p1, *p1 = *p2, *p2 = c;
		p1++;
	}
	sortbas = Gvp;
}

static
expand(as)
	char *as;
{
	register char *cs;
	register char *sgpathp, *oldcs;
	struct stat stb;

	sgpathp = gpathp;
	cs = as;
	if (*cs == '~' && gpathp == gpath) {
		addpath('~');
		for (cs++; letter(*cs) || digit(*cs) || *cs == '-';)
			addpath(*cs++);
		if (!*cs || *cs == '/') {
			if (gpathp != gpath + 1) {
				*gpathp = 0;
				if (gethdir(gpath + 1))
					globerr = "Unknown user name after ~";
				strcpy(gpath, gpath + 1);
			} else
				strcpy(gpath, home);
			gpathp = strend(gpath);
		}
	}
	while (!any(*cs, globchars)) {
		if (*cs == 0) {
			if (!globbed)
				Gcat(gpath, "");
			else if (stat(gpath, &stb) >= 0) {
				Gcat(gpath, "");
				globcnt++;
			}
			goto endit;
		}
		addpath(*cs++);
	}
	oldcs = cs;
	while (cs > as && *cs != '/')
		cs--, gpathp--;
	if (*cs == '/')
		cs++, gpathp++;
	*gpathp = 0;
	if (*oldcs == '{') {
		execbrc(cs, ((char *)0));
		return;
	}
	matchdir(cs);
endit:
	gpathp = sgpathp;
	*gpathp = 0;
}

static
matchdir(pattern)
	char *pattern;
{
	struct stat stb;
	register struct direct *dp;
	struct direct *readdir();
	int dirp;
	register int cnt;

	dirp = opendir(gpath);
	if (dirp == NULL) {
		if (globbed)
			return;
		goto patherr2;
	}
	if (fstat(dirp, &stb) < 0)
		goto patherr1;
	if (!isdir(stb)) {
		errno = ENOTDIR;
		goto patherr1;
	}
	while ((dp = readdir(dirp)) != NULL) {
		if (dp->d_ino == 0)
			continue;
		if (match(dp->d_name, pattern)) {
			Gcat(gpath, dp->d_name);
			globcnt++;
		}
	}
	closedir(dirp);
	return;

patherr1:
	closedir(dirp);
patherr2:
	globerr = "Bad directory components";
}

static
execbrc(p, s)
	char *p, *s;
{
	char restbuf[BUFSIZ + 2];
	register char *pe, *pm, *pl;
	int brclev = 0;
	char *lm, savec, *sgpathp;

	for (lm = restbuf; *p != '{'; *lm++ = *p++)
		continue;
	for (pe = ++p; *pe; pe++)
	switch (*pe) {

	case '{':
		brclev++;
		continue;

	case '}':
		if (brclev == 0)
			goto pend;
		brclev--;
		continue;

	case '[':
		for (pe++; *pe && *pe != ']'; pe++)
			continue;
		continue;
	}
pend:
	brclev = 0;
	for (pl = pm = p; pm <= pe; pm++)
	switch (*pm & (QUOTE|TRIM)) {

	case '{':
		brclev++;
		continue;

	case '}':
		if (brclev) {
			brclev--;
			continue;
		}
		goto doit;

	case ','|QUOTE:
	case ',':
		if (brclev)
			continue;
doit:
		savec = *pm;
		*pm = 0;
		strcpy(lm, pl);
		strcat(restbuf, pe + 1);
		*pm = savec;
		if (s == 0) {
			sgpathp = gpathp;
			expand(restbuf);
			gpathp = sgpathp;
			*gpathp = 0;
		} else if (amatch(s, restbuf))
			return (1);
		sort();
		pl = pm + 1;
		if (brclev)
			return (0);
		continue;

	case '[':
		for (pm++; *pm && *pm != ']'; pm++)
			continue;
		if (!*pm)
			pm--;
		continue;
	}
	if (brclev)
		goto doit;
	return (0);
}

static
match(s, p)
	char *s, *p;
{
	register int c;
	register char *sentp;
	char sglobbed = globbed;

	if (*s == '.' && *p != '.')
		return (0);
	sentp = entp;
	entp = s;
	c = amatch(s, p);
	entp = sentp;
	globbed = sglobbed;
	return (c);
}

static
amatch(s, p)
	register char *s, *p;
{
	register int scc;
	int ok, lc;
	char *sgpathp;
	struct stat stb;
	int c, cc;

	globbed = 1;
	for (;;) {
		scc = *s++ & TRIM;
		switch (c = *p++) {

		case '{':
			return (execbrc(p - 1, s - 1));

		case '[':
			ok = 0;
			lc = 077777;
			while (cc = *p++) {
				if (cc == ']') {
					if (ok)
						break;
					return (0);
				}
				if (cc == '-') {
					if (lc <= scc && scc <= *p++)
						ok++;
				} else
					if (scc == (lc = cc))
						ok++;
			}
			if (cc == 0)
				if (ok)
					p--;
				else
					return 0;
			continue;

		case '*':
			if (!*p)
				return (1);
			if (*p == '/') {
				p++;
				goto slash;
			}
			s--;
			do {
				if (amatch(s, p))
					return (1);
			} while (*s++);
			return (0);

		case 0:
			return (scc == 0);

		default:
			if (c != scc)
				return (0);
			continue;

		case '?':
			if (scc == 0)
				return (0);
			continue;

		case '/':
			if (scc)
				return (0);
slash:
			s = entp;
			sgpathp = gpathp;
			while (*s)
				addpath(*s++);
			addpath('/');
			if (stat(gpath, &stb) == 0 && isdir(stb))
				if (*p == 0) {
					Gcat(gpath, "");
					globcnt++;
				} else
					expand(p);
			gpathp = sgpathp;
			*gpathp = 0;
			return (0);
		}
	}
}

static
Gmatch(s, p)
	register char *s, *p;
{
	register int scc;
	int ok, lc;
	int c, cc;

	for (;;) {
		scc = *s++ & TRIM;
		switch (c = *p++) {

		case '[':
			ok = 0;
			lc = 077777;
			while (cc = *p++) {
				if (cc == ']') {
					if (ok)
						break;
					return (0);
				}
				if (cc == '-') {
					if (lc <= scc && scc <= *p++)
						ok++;
				} else
					if (scc == (lc = cc))
						ok++;
			}
			if (cc == 0)
				if (ok)
					p--;
				else
					return 0;
			continue;

		case '*':
			if (!*p)
				return (1);
			for (s--; *s; s++)
				if (Gmatch(s, p))
					return (1);
			return (0);

		case 0:
			return (scc == 0);

		default:
			if ((c & TRIM) != scc)
				return (0);
			continue;

		case '?':
			if (scc == 0)
				return (0);
			continue;

		}
	}
}

static
Gcat(s1, s2)
	register char *s1, *s2;
{
	register int len = strlen(s1) + strlen(s2) + 1;

	if (len >= gnleft || gargc >= GAVSIZ - 1)
		globerr = "Arguments too long";
	else {
		gargc++;
		gnleft -= len;
		gargv[gargc] = 0;
		gargv[gargc - 1] = strspl(s1, s2);
	}
}

static
addpath(c)
	char c;
{

	if (gpathp >= lastgpathp)
		globerr = "Pathname too long";
	else {
		*gpathp++ = c;
		*gpathp = 0;
	}
}

static
rscan(t, f)
	register char **t;
	int (*f)();
{
	register char *p, c;

	while (p = *t++) {
		if (f == tglob)
			if (*p == '~')
				gflag |= 2;
			else if (eq(p, "{") || eq(p, "{}"))
				continue;
		while (c = *p++)
			(*f)(c);
	}
}

static
scan(t, f)
	register char **t;
	int (*f)();
{
	register char *p, c;

	while (p = *t++)
		while (c = *p)
			*p++ = (*f)(c);
}

static
tglob(c)
	register char c;
{

	if (any(c, globchars))
		gflag |= c == '{' ? 2 : 1;
	return (c);
}

static
trim(c)
	char c;
{

	return (c & TRIM);
}


letter(c)
	register char c;
{

	return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_');
}

digit(c)
	register char c;
{

	return (c >= '0' && c <= '9');
}

any(c, s)
	register int c;
	register char *s;
{

	while (*s)
		if (*s++ == c)
			return(1);
	return(0);
}
blklen(av)
	register char **av;
{
	register int i = 0;

	while (*av++)
		i++;
	return (i);
}

char **
blkcpy(oav, bv)
	char **oav;
	register char **bv;
{
	register char **av = oav;

	while (*av++ = *bv++)
		continue;
	return (oav);
}

blkfree(av0)
	char **av0;
{
	register char **av = av0;

	while (*av)
		free(*av++);
	free((char *)av0);
}

static
char *
strspl(cp, dp)
	register char *cp, *dp;
{
	register char *ep = malloc((unsigned)(strlen(cp) + strlen(dp) + 1));

	if (ep == (char *)0)
		fatal("Out of memory");
	strcpy(ep, cp);
	strcat(ep, dp);
	return (ep);
}

static
char **
copyblk(v)
	register char **v;
{
	register char **nv = (char **)malloc((unsigned)((blklen(v) + 1) *
						sizeof(char **)));
	if (nv == (char **)0)
		fatal("Out of (   (   memory");

	return (blkcpy(nv, v));
}

static
char *
strend(cp)
	register char *cp;
{

	while (*cp)
		cp++;
	return (cp);
}
/*
 * Extract a home directory from the password file
 * The argument points to a buffer where the name of the
 * user whose home directory is sought is currently.
 * We write the home directory of the user back there.
 */
gethdir(home)
	char *home;
{
	register struct passwd *pp = getpwnam(home);

	if (pp == 0)
		return (1);
	strcpy(home, pp->pw_dir);
	return (0);
}
>
#include <sys/stunix/users/ftp/main.c                                                                                  444     322     145        16361  3621344635  10166                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)main.c	5.0 (CMC) 9/10/84";
#endif

/*
 * FTP User Program -- Command Interface.
 */

#include <CMC/sysdep.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <CMC/param.h>			/* for MAXPATHLEN */
#include <sys/ioctl.h>

#include <CMC/ftp.h>

#include <signal.h>
#include <stdio.h>
#include <CMC/errno.h>
#include <ctype.h>
#include <CMC/netdb.h>
#include <pwd.h>

#include "ftp_var.h"
#define  CTRL(c)		('c'&037)

int	intr();
int	lostpeer();
struct passwd *getpwnam();
struct passwd *getpwuid();
extern	char *home;

main(argc, argv)
	char *argv[];
{
	register char *cp;
	int top;
	struct passwd *pw;
	char homedir[MAXPATHLEN];

	servp = getservbyname("ftp", "tcp");
	if (servp == 0) {
		fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
		exit(1);
	}
	doglob = 1;
	interactive = 0;
	autologin = 1;
	argc--, argv++;
	while (argc > 0 && **argv == '-') {
		for (cp = *argv + 1; *cp; cp++)
			switch (*cp) {

			case 'd':
				options |= SO_DEBUG;
				debug++;
				break;
			
			case 'v':
				verbose++;
				break;

			case 't':
				trace++;
				break;

			case 'i':
				interactive = 1;
				break;

			case 'n':
				autologin = 0;
				break;

			case 'g':
				doglob = 0;
				break;

			default:
				fprintf(stderr,
				  "ftp: %c: unknown option\n", *cp);
				exit(1);
			}
		argc--, argv++;
	}
	fromatty = isatty(fileno(stdin));
	/*
	 * Set up defaults for FTP.
	 */
	strcpy(typename, "ascii"), type = TYPE_A;
	strcpy(formname, "non-print"), form = FORM_N;
	strcpy(modename, "stream"), mode = MODE_S;
	strcpy(structname, "file"), stru = STRU_F;
	strcpy(bytename, "8"), bytesize = 8;
	if (fromatty)
		verbose++;
	/*
	 * Set up the home directory in case we're globbing.
	 */
	pw = getpwnam(getlogin());
	if (pw == NULL)
		pw = getpwuid(getuid());
	if (pw != NULL) {
		home = homedir;
		strcpy(home, pw->pw_dir);
	}
	if (argc > 0) {
		if (setjmp(toplevel))
			exit(0);
		signal(SIGINT, intr);
		signal(SIGPIPE, lostpeer);
		setpeer(argc + 1, argv - 1);
	}
	top = setjmp(toplevel) == 0;
	if (top) {
		signal(SIGINT, intr);
		signal(SIGPIPE, lostpeer);
	}
	for (;;) {
		cmdscanner(top);
		top = 1;
	}
}

intr()
{

	longjmp(toplevel, 1);
}

lostpeer()
{
	extern FILE *cout;
	extern int data;

	if (cncted) {
		if (cout != NULL) {
			shutdown(fileno(cout), 1+1);
			fclose(cout);
			cout = NULL;
		}
		if (data >= 0) {
			shutdown(data, 1+1);
			(void) close(data);
			data = -1;
		}
		cncted = 0;
		printf ("Lost connection to %s\n", hostname);
	}
	longjmp(toplevel, 1);
}

char *
tail(filename)
	char *filename;
{
	register char *s;
	char *strrchr();
	
	while (*filename) {
		s = strrchr(filename, '/');
		if (s == NULL)
			break;
		if (s[1])
			return (s + 1);
		*s = '\0';
	}
	return (filename);
}

/*
 * Command parser.
 */
cmdscanner(top)
	int top;
{
	register struct cmd *c;
	struct cmd *getcmd();
	extern struct cmd cmdtab[];
	extern int help();

	if (!top)
		putchar('\n');
	for (;;) {
		if (fromatty) {
			printf("ftp> ");
			fflush(stdout);
		}
		if (gets(line) == 0) {
			if (feof(stdin)) {
				clearerr(stdin);
				putchar('\n');
			}
			break;
		}
		if (line[0] == 0)
			break;
		makeargv();
		c = getcmd(margv[0]);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			continue;
		}
		if (c == 0) {
			printf("?Invalid command\n");
			continue;
		}
		if (c->c_conn && !cncted) {
			printf ("Not connected.\n");
			continue;
		}
		(*c->c_handler)(margc, margv);
		if (bell && c->c_bell)
			putchar(CTRL(g));
		if (c->c_handler != help)
			break;
	}
	longjmp(toplevel, 0);
}

struct cmd *
getcmd(name)
	register char *name;
{
	register char *p, *q;
	register struct cmd *c, *found;
	register int nmatches, longest;

	longest = 0;
	nmatches = 0;
	found = 0;
	for (c = cmdtab; p = c->c_name; c++) {
		for (q = name; *q == *p++; q++)
			if (*q == 0)		/* exact match? */
				return (c);
		if (!*q) {			/* the name was a prefix */
			if (q - name > longest) {
				longest = q - name;
				nmatches = 1;
				found = c;
			} else if (q - name == longest)
				nmatches++;
		}
	}
	if (nmatches > 1)
		return ((struct cmd *)-1);
	return (found);
}

/*
 * Slice a string up into argc/argv.
 */
makeargv()
{
	char **argp;
	char *slurpstring();

	margc = 0;
	argp = margv;
	stringbase = line;		/* scan from first of buffer */
	argbase = argbuf;		/* store from first of buffer */
	while (*argp++ = slurpstring())
		margc++;
}

/*
 * Parse string into argbuf;
 * implemented with FSM to
 * handle quoting and strings
 */
char *
slurpstring()
{
	int got_one = 0;
	register char *sb = stringbase;
	register char *ap = argbase;
	char *tmp = argbase;		/* will return this if token found */

	if (*sb == '!') {		/* recognize ! as a token for shell */
		stringbase++;
		return ("!");
	}
S0:
	switch (*sb) {

	case '\0':
		goto OUT;

	case ' ':
	case '\t':
		sb++; goto S0;

	default:
		goto S1;
	}

S1:
	switch (*sb) {

	case ' ':
	case '\t':
	case '\0':
		goto OUT;	/* end of token */

	case '\\':
		sb++; goto S2;	/* slurp next character */

	case '"':
		sb++; goto S3;	/* slurp quoted string */

	default:
		*ap++ = *sb++;	/* add character to token */
		got_one = 1;
		goto S1;
	}

S2:
	switch (*sb) {

	case '\0':
		goto OUT;

	default:
		*ap++ = *sb++;
		got_one = 1;
		goto S1;
	}

S3:
	switch (*sb) {

	case '\0':
		goto OUT;

	case '"':
		sb++; goto S1;

	default:
		*ap++ = *sb++;
		got_one = 1;
		goto S3;
	}

OUT:
	if (got_one)
		*ap++ = '\0';
	argbase = ap;			/* update storage pointer */
	stringbase = sb;		/* update scan pointer */
	if (got_one)
		return(tmp);
	return((char *)0);
}

#define HELPINDENT (sizeof ("directory"))

/*
 * Help command.
 * Call each command handler with argc == 0 and argv[0] == name.
 */
help(argc, argv)
	int argc;
	char *argv[];
{
	register struct cmd *c;

	if (argc == 1) {
		register int i, j, w;
		int columns, width = 0, lines;
		extern int NCMDS;

		printf("Commands may be abbreviated.  Commands are:\n\n");
		for (c = cmdtab; c < &cmdtab[NCMDS-1]; c++) {
			int len = strlen(c->c_name);

			if (len > width)
				width = len;
		}
		width = (width + 8) &~ 7;
		columns = 80 / width;
		if (columns == 0)
			columns = 1;
		lines = (NCMDS + columns - 1) / columns;
		for (i = 0; i < lines; i++) {
			for (j = 0; j < columns; j++) {
				c = cmdtab + j * lines + i;
				if (c->c_name)
					printf("%s", c->c_name);
				if (c + lines >= &cmdtab[NCMDS]) {
					printf("\n");
					break;
				}
				w = strlen(c->c_name);
				while (w < width) {
					w = (w + 8) &~ 7;
					putchar('\t');
				}
			}
		}
		return;
	}
	while (--argc > 0) {
		register char *arg;
		arg = *++argv;
		c = getcmd(arg);
		if (c == (struct cmd *)-1)
			printf("?Ambiguous help command %s\n", arg);
		else if (c == (struct cmd *)0)
			printf("?Invalid help command %s\n", arg);
		else
			printf("%-*s\t%s\n", HELPINDENT,
				c->c_name, c->c_help);
	}
}

/*
 * Call routine with argc, argv set from args (terminated by 0).
 */
/* VARARGS2 */
call(routine, args)
	int (*routine)();
	int args;
{
	register int *argp;
	register int argc;

	for (argc = 0, argp = &args; *argp++ != 0; argc++)
		;
	(*routine)(argc, &args);
}
= "Arguments too long";
	else {
		gargc++;
		gnleft -= len;
		gargv[gargc] = 0;
		gargv[gargc - 1] = strspl(s1, s2);
	}
}

static
addpath(c)
	char c;
{

	if (gpathp >= lastgpathp)
		globerr = "Pathname too long";
	else {
		*gpathp++ = c;
		*gpathp = 0;
	}
}

static
rscanunix/users/Makefile                                                                                    444     322     145         1627  3621344636   7725                                                                                                                                                                                                                                                                                                                                                                      #	/*
#	 *	Copyright (c) 1984, Communication Machinery Corporation
#	 */
#	
#	/*
#	 *	This file contains material and information which is
#	 *	proprietary to Communication Machinery Corporation, and
#	 *	which may not be divulged without the express written
#	 *	permission of Communication Machinery Corporation.
#	 */

# Makefile 9/12/84

CFLAGS= -O -I../include
LIBS= -lcmcnet

all: rsh rlogin rcp telnet ntest server sink

telnet: telnet.o
	${CC} -o telnet telnet.o ${LIBS}
	chmod u+s telnet

rsh: rsh.o
	${CC} -o rsh rsh.o ${LIBS}
	chmod u+s rsh

rcp: rcp.o
	${CC} -o rcp rcp.o ${LIBS}
	chmod u+s rcp

rlogin: rlogin.o
	${CC} -o rlogin rlogin.o ${LIBS}
	chmod u+s rlogin

ntest: ntest.o
	${CC} -o ntest ntest.o ${LIBS}

server:	server.o
	${CC} -o server server.o ${LIBS}
	chmod u+s server

sink: sink.o
	${CC} -o sink sink.o ${LIBS}
	chmod u+s sink

clean:
	rm -f telnet.o core a.out rcp.o rsh.o ntest.o server.o 
[];
{
	register char *cp;
	int top;
	struct passwd *pw;
	char homedir[MAXPATHLEN];

	servp = getservbynam (   (  unix/users/README                                                                                      444     322     145          621  3621344636   7116                                                                                                                                                                                                                                                                                                                                                                      
	These are the user side of the various network services.
Rcp and rsh must run SUID root, so their protection scheme remains
intact.  Telnet is more forgiving, and does not need SUID.

	Rcp must reside one of the standard search directories,
i.e. /bin or /usr/bin, in order to be found by rshd when doing remote
copies.

	The Makefile assumes that you have compiled "../lib" and built a
libcmcnet.a.
telnet ntest server sink

telnet: telnet.o
	${CC} -o telnet telnet.o ${LIBS}
	chmod u+s telnet

rsh: rsh.o
	${Cunix/users/ntest.c                                                                                     444     322     145        56444  3621344640   7610                                                                                                                                                                                                                                                                                                                                                                      /*
 *	ntest				D. M. Miller C.M.C. 7/85
 *
 *	  Provides two "network" server/user functions; source a data
 *	stream and sink a data stream, and a system "calibration" function.
 *	Data are sent/received using either "raw" Ethernet packets, a TCP
 *	stream, UDP datagrams, or raw Internet datagrams.
 *
 *	  The calibration computes data rates (for this program) for reading
 *	a disk file, writing an internal buffer to /dev/null, and reading a
 *	disk file and writing to /dev/null.
 *
 *	  The "service" ports are used as either a TCP/UDP logical port (if
 *	run at the I_NET level) or the Ethernet packet type if run at the
 *	"raw" level.
 *
 *	Program Requirements
 *
 *	1. C.M.C TCP/IP Package (or like software - 4.2 BSD User Interface)
 *	2. User Library of above user level functions.
 *	3. User level include files.
 *	4. A "source/sink" file if doing a calibration run.
 *
 *	Program Option Switches
 *
 *	  If the "-p x" option is specified, the "x" value determines which
 *	socket type (protocol) is to be used. The default protocol is TCP
 *	stream. By specifying t, u, i, or e; TCP, UDP, Raw Internet, or Raw
 *	Ethernet may be selected.
 *
 *	  If the "-f" option is specified, the given file will be used
 *	as either the data source or the data sink.
 *
 *	  If the "-v" option is specified, packets/buffers will be displayed
 *	at the end of a test run (last sent/received) with an attempt at
 *	"decoding" the headers.
 *
 *	  If the "-l" option is specified, the program will perform the
 *	test function "forever".
 *
 *	  If the "-s" option is specified, the given value will be used as
 *	the packet/buffer size. Otherwise, the default size of 1,024 bytes
 *	will be used.
 *
 *	  If the "-i" option is specified, the given value will be used as
 *	the iteration count (number of packets to send/recv). Otherwise, the
 *	default count of 1,000 will be used.
 *
 *	  If the "-h" option is specified, the given NAME will be used as
 *	the foreign host for the session. Otherwise, the default host
 *	BBOARD (back-board) will be used. The specified host must be
 *	defined in the node[] structure.
 */


# include <CMC/longnames.h>
# include <CMC/types.h>
# include <CMC/socket.h>
# include <CMC/in.h>
# include <CMC/eth.h>
# include <CMC/errno.h>

# include <fcntl.h>

/*
 *		Global "sizing" definitions
 */

# define	MAX_DATA	1500		/* Most data we do	*/
# define	MAX_TCP		1460		/* Most for TCP Stream	*/
# define	MAX_UDP		1472		/* Most for UDP Dgrams	*/
# define	MAX_RIP		1480		/* Most for IP Dgrams	*/

# define	OneK		1024


/*
 *		Definitions for "raw" Ethernet mode
 */

# define	ETH_HDR_SIZE	14		/* Size of ether header	*/
# define	SLOP		4		/* -4 bytes on transmit	*/



/*
 *		Host/Node Definitions
 */

# define	BBOARD		0		/* Index to bboard	*/
# define	MY_NODE		1		/* Index to us ...	*/

typedef struct	node {
	char	*n_name;			/* Node's name		*/
	long	n_iaddr;			/* Internet address	*/
	char	n_eaddr[6];			/* Ethernet address	*/
} NODE;

NODE	node_tab[] = {				/* Nodes we know about	*/
	{"bboard", 0x59000055, {0x08, 0x00, 0x14, 0x00, 0x00, 0x55} },
	{"cyb", 0x59000054, {0x02, 0xCF, 0x1F, 0x10, 0x01, 0x19} },
	{"vme", 0x59000059, {0x08, 0x00, 0x14, 0x00, 0x00, 0x59} },
	{"masscomp", 0x59000034, {0x08, 0x00, 0x14, 0x00, 0x00, 0x34} },
	{"yin", 0x59000086, {0x08, 0x00, 0x14, 0x00, 0x00, 0x86} },
	{"yang", 0x59000087, {0x02, 0xCF, 0x1F, 0x20, 0x01, 0x29} },
	{"dewey", 0x59000090, {0x08, 0x00, 0x14, 0x00, 0x00, 0x90} },
	{"fred", 0x59000059, {0x08, 0x00, 0x14, 0x00, 0x00, 0x59} },
	{"vms", 0x59000058, {0x08, 0x00, 0x14, 0x00, 0x00, 0x58} },
	{"vax", 0x59000079, {0x08, 0x00, 0x14, 0x00, 0x00, 0x79} },
	{"olive", 0x59000035, {0x08, 0x00, 0x14, 0x00, 0x00, 0x35} },
	{"puppie", 0x59000020, {00, 00, 00, 00, 00, 00} },
	{"bcast", 0xFFFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} },
	{"blackhole", 0x59000099, {0x08, 0x00, 0x14, 0x00, 0x00, 0x99} },
	{"anyhost", 0x00000000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
};
short	nodes = sizeof(node_tab) / sizeof(node_tab[0]);

					/* Needed node_tab indexes	*/
short	bboard = BBOARD;			/* Backboard		*/
short	my_node = MY_NODE;			/* Node we are in	*/

NODE	*getaddr(), *getname();


/*
 *		Network "services"
 */

# define	SINK		2009		/* Sink socket		*/
# define	SOURCE		2019		/* Source socket	*/
# define	CALIBRATE	0		/* Do calibration	*/

typedef struct	srv {
	char	*s_func;		/* Requested "function"		*/
	char	*s_name;		/* Name of service at foreign	*/
	short	s_port;			/* INET port we connect to	*/
	short	s_raw;			/* raw Ethernet port we use	*/
} SRV;

SRV	services[] = {
	{"send", "sink", SINK, SOURCE},
	{"recv", "source", SOURCE, SINK},
	{"cal", "", CALIBRATE, CALIBRATE}
};
short nsrv = sizeof(services) / sizeof(services[0]);

short	getserv();


/*
 *		For packet dump routines
 */

typedef struct	proto {
	char	*pro_name;			/* Protocol name	*/
	short	pro_type;			/* Ethernet type	*/
} PROTO;

PROTO	proto_tab[] = {
	{"DoD Internet", 0x0800},
	{"XNS Internet", 0x0600},
	{"Raw Ethernet - CMC Sink", SINK},
	{"Raw Ethernet - CMC Source", SOURCE},
	{"Ethernet - ARP Packet", 0x806}
};
int	protos = sizeof(proto_tab) / sizeof(proto_tab[0]);

PROTO	*getproto();


/*
 *		Socket Interfaces
 *	Either DoD Internet or "raw" Ethernet
 */

/*		DoD Internet			*/

struct
sockaddr_in	to;				/* "connect" socket	*/

struct
sockaddr_in	ls_addr;			/* "listen" socket	*/

struct
sockaddr_in	from;				/* "work" socket	*/
int		flen = sizeof(from);

typedef struct	typnam {
	char	*tn_name;			/* Type's name		*/
	short	tn_type;			/* Socket "type"	*/
} TYPNAM;

TYPNAM	typ_names[] = {
	{ "TCP Stream", SOCK_STREAM },
	{ "UDP Datagram", SOCK_DGRAM },
	{ "IP Datagram", SOCK_RAW }
};
short	ntype = sizeof(typ_names) / sizeof(TYPNAM);

TYPNAM	*getype();



/*		Raw Ethernet			*/

struct
sockaddr_eth	eth_addr;			/* For AF_ETHER sockets	*/


/*
 *		Test Specific
 */

# define	T_SIZE		OneK	/* Default data size		*/
# define	T_COUNT		1000	/* Default iterations		*/

long		t_in, t_out;		/* Total bytes in/out		*/
long		p_tot, pps;		/* Packets/second		*/
long		b_tot, bps;		/* Kilo-bits/second		*/
long		et;			/* Elapsed time (+/- sec)	*/

NODE		*t_node;		/* Foreign node/host and	*/
SRV		*t_srv;			/* Service we are running	*/
char		*t_name;		/* Socket "type" name using	*/
short		t_port;			/* Foreign port for service	*/
int		t_family;		/* Family (domain) to use	*/
int		t_type;			/* Type (proto) we are using	*/
int		t_sock;			/* Socket we are using		*/
long		t_maxsize;		/* Max data allowed		*/
long		t_size;			/* Data buffer size		*/
char		*t_buff;		/* Send/recv buffer (data)	*/
int		*p_seq;			/* Seq # pointer into pkt	*/
int		t_seq;			/* Sequence number		*/
long		t_count;		/* Bytes to be transferred	*/
long		t_start, t_stop;	/* Start/stop times		*/

/*	If using a disk file ..		*/

char		*d_file;		/* File name to read/write	*/
char		*d_buff;		/* Pointer to data buffer	*/
int		d_fid;			/* File descriptor		*/

/*	If doing forever ..		*/

long		iteration = 0;		/* Iteration counter		*/
long		refresh;		/* Inner loop refresh		*/


/*
 *		Raw Ethernet Packet formats
 *		or INET buffer
 */

typedef struct	pkt {
	char	p_daddr[6];		/* Destination address		*/
	char	p_saddr[6];		/* Source      address		*/
	short	p_type;			/* Ethernet Packet type		*/
	char	p_buff[MAX_DATA];	/* Data buffer			*/
	long	p_fsck;			/* Frame seq check		*/
} PKT;

PKT	t_pkt;				/* Transmit/receive "pkt"	*/

int	p_size;				/* Total packet size		*/


/*
 *		User/Unix Interface
 */

short	r_flag = 0;			/* Run time options		*/
#define	VERBOSE		0x0001			/* Do packet dumps	*/
#define	DISK		0x0002			/* Using a disk file	*/
#define	CAL		0x0004			/* Calibration		*/
#define	FOREVER		0x0008			/* Looping test ...	*/
#define	SEND		0x0010			/* We are data source	*/
#define	RECV		0x0020			/* We are data sink	*/
#define	DGRAM		0x8000			/* Doing Datagrams	*/

char	*u_txt =			/* Usage line			*/
"send|recv|cal -f <file> -p <t|u|i|e> -h <host> -s <size> -i <iterations>\n";

int		mypid;			/* Our Unix PID			*/
extern int	errno;



main(argc, argv)
char	*argv[];
{
	register TYPNAM	*typ;

	getparams(--argc, ++argv);
	mypid = getpid();
	if (t_family == AF_INET) {
		typ = getype(t_type);
		t_name = typ->tn_name;
	}
	else
		t_name = "Ethernet Datagrams";

	if (r_flag & FOREVER)
		refresh = t_count;

loop:					/* If doing forever ...		*/
	printf("\n");
	if (r_flag & FOREVER)
		printf("<%d> Iteration: %d\n", mypid, ++iteration);

	if (r_flag & CAL)
		printf("<%d> Doing calibration run.\n", mypid);
	else {
		printf("<%d> %s data to/from %s port at host %s:%x\n", mypid,
		t_srv->s_func, t_srv->s_name, t_node->n_name, t_node->n_iaddr);
	}

	if (r_flag & DISK) {
		if ((d_fid = open(d_file, (O_RDWR | O_CREAT), 0666)) < 0) {
			perror("File open - ");
			exit(1); (   (  
		}
		d_buff = (char *) t_pkt.p_buff[0];
		printf("<%d> Using file %s.", mypid, d_file);
	}
	else
		printf("<%d> Using internal data buffer.", mypid);

	printf(" Buffer/packet size is %d bytes.\n", t_size);
	printf("<%d> Protocol type is %s.\n", mypid, t_name);

	t_in = t_out = 0;
	t_seq = 1;
	initpkt(&t_pkt);

	switch (t_port) {	/* Switch on foreign service port	*/
		case SINK:
			r_flag |= SEND;
			do_source();
			break;
	
		case SOURCE:
			r_flag |= RECV;
			do_sink();
			break;

		case CALIBRATE:
			do_cal();
			break;
	}
	
	close(t_sock);
	if (r_flag & DISK)
		close(d_fid);
	
	if ((r_flag & CAL) == 0)
		do_stats();

	if (r_flag & FOREVER) {
		if (r_flag & SEND)
			sleep(4);	/* Give server time to listen	*/
		t_count = refresh;
		goto loop;
	}
}


/*
 *		Function: receive
 *		Foreign Port/Service: Data Generator
 *		Local Port/Service: Data Sink
 *		If DISK: Use <file> as data sink.
 */

do_sink()
{
	register int	cnt;
	register int	first = 1;

	do_open(t_family, t_type);

	do {
		if ((cnt = readpkt()) <= 0) {
			if (cnt < 0)
				perror("recv - network read");
			else
				printf("<%d> Remote closed.\n", mypid);
			break;
		}

		if (first) {
			first = 0;
			t_start = time(0);
		}

		t_in += cnt;

		if (r_flag & VERBOSE) {
			if (r_flag & DGRAM) {
				dumpaddr("Input - ", &from, flen);
				dumppkt(0, &t_pkt, 0);
			}
			else
				dumppkt("Input - ", &t_pkt, 0);
		}

		if ((r_flag & DISK) && (write(d_fid, d_buff, cnt) <= 0)) {
			perror("recv - disk write");
			break;
		}
	} while (1);		/* Sink as long as incoming data	*/

	t_stop = time(0);
}


/*
 *		Function: Send
 *		Foreign Port/Service: Data Sink
 *		Local Port/Service: Data Generator
 *		If DISK: Use <file> as data source.
 *
 *		NOTE: We will sleep for 3 seconds before sending
 *		      any data - this will ensure that the sinking
 *		      node has has time for any "set-up".
 */

do_source()
{
	register int	cnt;

	if ((r_flag & DISK) == 0)
		t_count *= t_size;

	do_open(t_family, t_type);

	sleep(3);
	t_start = time(0);

	do {
		if (r_flag & DISK) {
			if ((cnt = read(d_fid, d_buff, t_size)) <= 0) {
				if (cnt < 0)
					perror("send - disk read");
				break;
			}
		}
		else
			cnt = p_size;

		if ((cnt = sendpkt(cnt)) <= 0) {
			if (cnt < 0)
				perror("send - network write");
			else
				printf("<%d> Remote closed.\n", mypid);
			break;
		}

		t_out += cnt;

		if ((r_flag & DISK) == 0)
			t_count -= cnt;
	} while (t_count > 0);

	t_stop = time(0);
}


/*
 *		Function: Calibration
 */

do_cal()
{
	cal_disk();			/* Run disk calibration		*/
	cal_null();			/* Run /dev/null calibration	*/
	cal_path();			/* Run disk -> /dev/null cal	*/
}


/*
 *		do_open(family, type)
 */

do_open(family, type)
{
	if (family == AF_INET)
		in_open(type);
	else
		eth_open();
}


/*
 *		do_stats()
 *
 *	Compute and display packets/second and kilo-bits/second
 */

do_stats()
{
	if (t_start) {			/* We ever get going?	*/
		if ((et = t_stop - t_start) <= 0)
			et = 1;
	
		p_tot = (t_in + t_out)/t_size;	/* ~ Total packets	*/
		pps = p_tot/et;			/* Packets/second	*/

		b_tot = (t_in + t_out) * 8;	/* Total bits		*/
		bps = (b_tot/et)/1000;		/* Kilo-bits/second	*/
	}

	if (r_flag & RECV)
		printf("<%d> Received %d packets in %d seconds -- ",
			mypid, p_tot, et);
	else
		printf("<%d> Sent %d packets in %d seconds -- ",
			mypid, p_tot, et);
	printf("%d pps @ %d Kbs\n", pps, bps);
	t_in = t_out = 0;
}


/*
 *		in_open(type)
 *
 *	Open Internet socket; either Stream, Datagram, or Raw.
 *	Depending on foreign service, we will either connect or listen.
 */

in_open(type)
{
	p_size = t_size;		/* Packet & Buffer same		*/
	t_buff = t_pkt.p_buff;
	p_seq = (int *) t_buff;

	switch (t_port) {
		case SINK:		/* We source to SINK	*/
			to.sin_family = AF_INET;
			to.sin_port = t_port;
			to.sin_addr.s_addr = t_node->n_iaddr;
			switch (type) {
				case SOCK_DGRAM:
					udp_open(0);
					break;
				case SOCK_RAW:
					rip_open();
					break;
				case SOCK_STREAM:
					tcp_open();
					break;
			}
			break;

		case SOURCE:		/* We sink from SOURCE	*/
			ls_addr.sin_family = AF_INET;
			ls_addr.sin_port = SINK;
			switch (type) {
				case SOCK_DGRAM:
					udp_open(SINK);
					break;
				case SOCK_RAW:
					rip_open();
					break;
				case SOCK_STREAM:
					tcp_listen();
					break;
			}
			break;
	}
}


/*
 *		eth_open()
 *
 *	Open Ethernet (RAW) type socket ...
 */

eth_open()
{
	p_size = t_size + ETH_HDR_SIZE;
	if (r_flag & RECV)
		p_size += SLOP;
	t_buff = (char *) &t_pkt;
	p_seq = (int *) t_pkt.p_buff;

	if ((t_sock = socket(AF_ETHER, SOCK_RAW, 0)) < 0) {
		perror("eth_open - Socket allocation failed");
		exit(1);
	}

	eth_addr.sen_type = t_srv->s_raw;

	if ((bind(t_sock, &eth_addr, sizeof(eth_addr))) < 0) {
		perror("eth_open - Bind failed");
		exit(1);
	}

	printf("<%d> Network opened.\n", mypid);
}


/*
 *		tcp_open()
 *
 *	Do "active" TCP open - i.e., a connect.
 */

tcp_open()
{
	register short	try = 10;

	while (1) {
		if ((t_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			perror("tcp_open - Socket allocation failed");
			exit(1);
		}

		if (connect(t_sock, &to, sizeof(to)) < 0) {
			perror("tcp_open - Connect failed");
			if (--try) {
				close(t_sock);
				printf("<%d> tcp_open - Retry %d\n",
					mypid, 10 - try);
				sleep(1);
				continue;
			}
			exit(1);
		}
		break;
	}

	printf("<%d> Connection established.\n", mypid);
}


/*
 *		tcp_listen()
 *
 *	Build sockaddr_in struct for the listen, get a socket, bind
 *	to it, issue a listen call, and then accept on the socket.
 *	When we get a hit, we complete the connect sequence and
 *	return the "connect" socket (not the listen socket).
 */

tcp_listen()
{
	register int	ls;
	register short	try = 10;
	int		size;

	if ((ls = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
		perror("tcp_listen - Socket allocation failed!");
		exit(1);
	}

	if (bind(ls, &ls_addr, sizeof(ls_addr)) < 0 ) {
		perror("tcp_listen - Bind failed!");
		exit(1);
	}

	if (listen(ls, 1) < 0) {
		perror("tcp_listen - Listen failed!");
		exit(1);
	}

	size = sizeof(struct sockaddr_in);

	while (1) {
		if ((t_sock = accept(ls, &to, &size)) < 0) {
			perror("tcp_listen - Accept failed!");
			if (--try) continue;
			exit(1);
		}
		break;
	}
	close(ls);

	printf("<%d> Connection established.\n", mypid);
}


/*
 *		udp_open()
 *
 *	Get and bind to a UDP port for doing sendto() recvfrom() on.
 */

udp_open(lport)
register short	lport;
{
	if ((t_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("udp_open - Socket allocation failed");
		exit(1);
	}

	/*	Set up local address/port	*/

	ls_addr.sin_family = AF_INET;
	ls_addr.sin_port = lport;
	ls_addr.sin_addr.s_addr = 0;

	if (bind(t_sock, &ls_addr, sizeof(ls_addr)) < 0) {
		perror("udp_open - Bind failed>");
		exit(1);
	}

	printf("<%d> Network opened.\n", mypid);
}


/*
 *		rip_open()
 *
 *	Get and bind to a RIP port for doing sendto() recvfrom() on.
 */

rip_open()
{
	if ((t_sock = socket(AF_INET, SOCK_RAW, 0)) < 0) {
		perror("rip_open - Socket allocation failed");
		exit(1);
	}

	if (t_port == SOURCE) {
		ls_addr.sin_family = AF_INET;
		ls_addr.sin_port = 0;
		ls_addr.sin_addr.s_addr = 0;

		if (bind(t_sock, &ls_addr, sizeof(ls_addr)) < 0) {
			perror("rip_open - Bind failed>");
			exit(1);
		}
	}

	printf("<%d> Network opened.\n", mypid);
}


/*
 *		System calibration routines
 *
 *	cal_disk()	::=	Speed we can read a disk at (kilo bps)
 *	cal_null()	::=	Speed we can write /dev/null at.
 *	cal_path()	::=	Speed we can read and write at.
 */

cal_disk()
{
	register int	cnt;

	printf("<%d> Disk read calibration -\n", mypid);
	if ((r_flag & DISK) == 0) {
		printf("<%d> Can't calibrate - need input file!\n", mypid);
		exit(1);
	}

	t_start = time(0);
	do {
		if ((cnt = read(d_fid, t_buff, t_size)) <= 0)
			break;
		t_in += cnt;
	} while (1);
	t_stop = time(0);

	t_count = t_in;			/* Set limit for cal_null()	*/
	do_stats();
}


cal_null()
{
	register int	cnt;

	printf("<%d> /dev/null write calibration -\n", mypid);
	if ((t_sock = open("/dev/null", O_RDWR)) < 0 ) {
		printf("<%d> Can't open /dev/null\n", mypid);
		exit(1);
	}

	t_start = time(0);
	do {
		if ((cnt = write(t_sock, t_buff, t_size)) <= 0)
			break;
		t_out += cnt;
	} while ((t_count -= cnt) > 0);
	t_stop = time(0);

	do_stats();
}


cal_path()
{
	register int	cnt;

	printf("<%d> Disk to /dev/null calibration -\n", mypid);
	lseek(d_fid, 0, 0);

	t_start = time(0);
	do {
		if ((cnt = read(d_fid, t_buff, t_size)) <= 0)
			break;
		t_in += cnt;
		if ((cnt = write(t_sock, t_buff, cnt)) <= 0)
			break;
		t_out += cnt;
	} while (1);
	t_stop = time(0);

	t_out = 0;		/* Don't include in computation	*/
	do_stats();
}


/*
 *		User Parameter Input Specific Code
 *
 *	getparams()	::=	Parse user's parameter line
 *	setprot()	::=	Parse protocol portion of line
 *	getserv()	::=	Requested service -> foreign port
 *	getype()	::=	Socket type -> type's name
 *	getaddr()	::=	Given name -> node's network addresses
 *	getname()	::=	Given network address -> node's name
 *	getproto()	::=	Given Ethernet type -> protocol name
 */

getparams(argc, argv)
char	*argv[];
{
	register char	*p;

	if (argc < 1) {
		printf("%s", u_txt);
		exit(1);
	}

	if ((t_port = getserv(*argv++)) < 0) {
		printf("Service? [recv|send|cal]\n");
		exit(1);
	}

	if (t_port == CALIBRATE)
		r_flag = CAL;
	else
		r_flag = 0;

	t_size = T_SIZE; t_count = T_COUNT; t_node = &node_tab[bboard];
	t_family = AF_INET; t_type = SOCK_STREAM; t_maxsize = MAX_TCP;

	if (--argc == 0)		/* All defaults		*/
		return;

	while (argc) {
		p = *argv++; argc--;
		if (*p++ == '-')
		switch (*p) {
			case 'p':	/* Set protocol			*/
				argc--;
				setprot(*argv++);
				break;

			case 'h':	/* Foreign host name		*/
				argc--;
				if ((t_node = getaddr(*argv++)) == 0) {
					printf("Host?\n");
					exit(1);
				}
				break;

			case 's':	/* Set packet (data) size	*/
				argc--;
				t_size = (int) atoi(*argv++);
				if ((t_size > t_maxsize) || (t_size <= 0)) {
					printf("Size?\n");
					exit(1);
				}
				break;

			case 'i':	/* Set run iteration count	*/
				argc--;
				t_count = (int) atoi(*argv++);
				break;

			case 'v':	/* Set verbose mode		*/
				r_flag |= VERBOSE;
				break;

			case 'f':	/* Using disk file		*/
				argc--;
				d_file = *argv++;
				r_flag |= DISK;
				break; (   (  

			case 'l':	/* Doing forever mode ..	*/
				r_flag |= FOREVER;
				break;

			default:
				printf("%s", u_txt);
				exit(1);
		}
	}
}


setprot(p)
register char	*p;
{
	switch (*p) {
		case 'e':		/* Use raw Ethernet		*/
			t_family = AF_ETHER;
			t_type = SOCK_RAW;
			t_maxsize = MAX_DATA;
			break;

		case 'u':		/* Use UDP			*/
			t_type = SOCK_DGRAM;
			t_maxsize = MAX_UDP;
			r_flag |= DGRAM;
			break;

		case 'i':		/* Use raw Internet		*/
			t_type = SOCK_RAW;
			t_maxsize = MAX_RIP;
			r_flag |= DGRAM;
			break;

		case 't':		/* Use TCP stream		*/
			t_type = SOCK_STREAM;
			t_maxsize = MAX_TCP;
			break;

		default:
			printf("Protocol?\n");
			exit(1);
	}
}


short
getserv(name)
register char	*name;
{
	register short	i;

	for (i = 0; i < nsrv; i++)
	if ((strcmp(name, services[i].s_func)) == 0) {
		t_srv = &services[i];
		return (services[i].s_port);
	}
	return (-1);
}


NODE *
getaddr(name)
register char	*name;
{
	register NODE	*np;

	for (np = node_tab; np < &node_tab[nodes]; np++)
	if ((strcmp(np->n_name, name)) == 0)
		return (np);

	return (0);
}


NODE *
getname(addr)
register int	addr;
{
	register NODE	*np;

	int		(*cmp_addr)();
	extern		eth_comp(), in_comp();

	if (t_family == AF_ETHER)
		cmp_addr = eth_comp;
	else
	if (t_family == AF_INET)
		cmp_addr = in_comp;
		
	for (np = node_tab; np < &node_tab[nodes]; np++)
	if ((*cmp_addr) (addr, np))
		return (np);

	return (0);
}


TYPNAM *
getype(type)
register short	type;
{
	register TYPNAM	*t;
	for (t = typ_names; t < &typ_names[ntype]; t++)
	if (type == t->tn_type)
		return (t);

	return (0);
}


eth_comp(addr, np)
register char	*addr;
register NODE	*np;
{
	register short	i;

	for (i = 0; i < 6; i++)
	if (addr[i] != np->n_eaddr[i]) {
		i = 0;
		break;
	}
	return (i);
}


in_comp(addr, np)
register long	addr;
register NODE	*np;
{
	return (addr == np->n_iaddr);
}


PROTO *
getproto(type)
register short	type;
{
	register PROTO	*p;

	for (p = proto_tab; p < &proto_tab[protos]; p++)
	if (p->pro_type == type)
		return (p);

	return (0);
}


/*
 *		Packet Routines
 *
 */

initpkt(p)
register PKT	*p;
{
	register short	i, j;
	register NODE	*me = &node_tab[my_node];

	for (i = 4, j = 0; i < t_size; i++, j++) {
		p->p_buff[i] = (char) (j + 0x30);
		if (j == 9) j = 0;
	}

	if (t_family == AF_ETHER) {
		p->p_type = t_port;
		for (i = 0; i < 6; i++) {
			p->p_daddr[i] = t_node->n_eaddr[i];
			p->p_saddr[i] = me->n_eaddr[i];
		}
	}
}


sendpkt(cnt)
register int	cnt;
{
	register int	count;

	if ((r_flag & DISK) == 0)
		*p_seq = t_seq++;	/* Store sequence number	*/

	if (r_flag & DGRAM)
		count = sendto(t_sock, t_buff, cnt, 0, &to, sizeof(to));
	else
		count = write(t_sock, t_buff, cnt);

	if (t_family == AF_ETHER)
		count -= ETH_HDR_SIZE;

	return (count);
}


readpkt()
{
	register int	count;

	if (r_flag & DGRAM)
		count = recvfrom(t_sock, t_buff, p_size, 0, &from, &flen);
	else
		count = read(t_sock, t_buff, p_size);

	if ((count > 0) && (t_family == AF_ETHER))
		count -= ETH_HDR_SIZE + SLOP;

	return (count);
}


/*
 *		Packet/buffer dump routines
 */

dumpaddr(msg, from, len)
register char	*msg;
register struct
sockaddr_in	*from;
register int	len;
{
	register NODE	*np;

	printf("\n<%d> ", mypid);
	if (msg)
		printf("%s", msg);
	printf("Source Host: ");
	if (np = getname(from->sin_addr.s_addr))
		printf("%s [", np->n_name);
	else
		printf("? [");
	phex(&from->sin_addr.s_addr, 4);
	printf("] Port: %d\n", from->sin_port);
}


dumppkt(msg, pp, flag)
register char	*msg;
register PKT	*pp;
{
	register NODE	*np;
	register PROTO	*pro;
	register int	bp;
	register int	blocks;

	int		count, rest, quit;

	if (t_family == AF_ETHER)
		count = p_size - ETH_HDR_SIZE;
	else
		count = p_size;

	blocks = count/30;
	rest = count - (blocks * 30);
	quit = 0;

	if (msg)
		printf("\n<%d> %s", mypid, msg);

	if (t_family == AF_ETHER) {	/* We have an Ethernet header	*/
		printf("Ethernet Header: ");
		phex((int) pp, ETH_HDR_SIZE);
		printf("\nDestination: ");
		if ((np = getname(pp->p_daddr)) == 0)
			printf("?");
		else
			printf("%s", np->n_name);
		printf("  Source: ");
		if ((np = getname(pp->p_saddr)) == 0)
			printf("?");
		else
			printf("%s", np->n_name);
		printf("  Type: ");
		if ((pro = getproto(pp->p_type)) == 0)
			printf("?\n");
		else
			printf("%s\n", pro->pro_name);
	}

	bp = (int) pp->p_buff;
	printf("Data Buffer:\n");
	while (blocks--) {
		phex(bp, 30);
		if (flag) {
			printf("\n");
			return;
		}
		printf(" more? ");
		if ((getchar()) != '\n') {
			while (getchar() != '\n');
			quit = 1;
			break;
		}
		bp += 30;
	}
	if (rest && !quit) {
		phex(bp, rest);
		printf("\n");
	}
}


/*
 *		General usage routines
 */

phex(bp, cnt)
register char	*bp;
int		cnt;
{
	register int	i;
	register char	c1, c2;

	static char hex_tab[] = "0123456789ABCDEF";

	for (i = 0; i < cnt; i++) {
		c1 = ((*bp&0xF0)>>4);
		c2 = (*bp++ & 0x0F);
		printf("%c%c",hex_tab[c1], hex_tab[c2]);
	}
}
 short	try = 10;

	while (1) {
		if ((t_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			perror("tcp_open - Socket allocation failed");
			exit(1);
		}

		if (connect(t_sock, &to, sizeof(to)) < 0) {
			perror("tcp_open unix/users/rcp.c                                                                                       444     322     145        26452  3621344640   7233                                                                                                                                                                                                                                                                                                                                                                      /*
 *      Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *      This file contains material and information which is
 *      proprietary to Communication Machinery Corporation, and
 *      which may not be divulged without the express written
 *      permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)rcp.c  (CMC) 5.0 9/21/84";
#endif

/*
 * rcp
 */
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <sys/param.h>
#include <sys/stat.h>

#include <CMC/in.h>

#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#include <ctype.h>
#include <CMC/errno.h>

int     rem;
char    *colon(), *strchr(), *strrchr(), *malloc(), *strcpy(), *sprintf();
int     errs;
int     lostconn();
int     iamremote;

int     errno;
char	*net_error();
int     iamremote, targetshouldbedirectory;
int     iamrecursive;
struct  passwd *pwd;
struct  passwd *getpwuid();

/*VARARGS*/
int     error();

#define ga()            (void) write(rem, "", 1)

main(argc, argv)
int argc;
char **argv;
{
	char *targ, *host, *src;
	char *suser, *tuser;
	int i;
	char buf[BUFSIZ], cmd[16];

	setpwent();
	pwd = getpwuid(getuid());
	endpwent();
	if (pwd == 0) {
		fprintf(stderr, "who are you?\n");
		exit(1);
	}
	argc--, argv++;
	if (argc > 0 && !strcmp(*argv, "-r")) {
		iamrecursive++;
		argc--, argv++;
	}
	if (argc > 0 && !strcmp(*argv, "-d")) {
		targetshouldbedirectory = 1;
		argc--, argv++;
	}
	if (argc > 0 && !strcmp(*argv, "-f")) {
		argc--, argv++; 
		iamremote = 1;
		(void) response();
		(void) setuid(getuid());
		source(argc, argv);
		exit(errs);
	}
	if (argc > 0 && !strcmp(*argv, "-t")) {
		argc--, argv++; 
		iamremote = 1;
		(void) setuid(getuid());
		sink(argc, argv);
		exit(errs);
	}
	rem = -1;
	if (argc > 2)
		targetshouldbedirectory = 1;
	(void) sprintf(cmd, "rcp%s%s",
	    iamrecursive ? " -r" : "", targetshouldbedirectory ? " -d" : "");
	signal(SIGPIPE, lostconn);
	targ = colon(argv[argc - 1]);
	if (targ) {
		*targ++ = 0;
		if (*targ == 0)
			targ = ".";
		tuser = strrchr(argv[argc - 1], '.');
		if (tuser) {
			*tuser++ = 0;
			if (!okname(tuser))
				exit(1);
		} else
			tuser = pwd->pw_name;
		for (i = 0; i < argc - 1; i++) {
			src = colon(argv[i]);
			if (src) {
				*src++ = 0;
				if (*src == 0)
					src = ".";
				suser = strrchr(argv[i], '.');
				if (suser) {
					*suser++ = 0;
					if (!okname(suser))
						continue;
					(void) sprintf(buf, "rsh %s -L %s -n %s %s '%s:%s'",
					    argv[i], suser, cmd,
					    src, argv[argc - 1], targ);
				} else
					(void) sprintf(buf, "rsh %s -n %s %s '%s:%s'",
					    argv[i], cmd,
					    src, argv[argc - 1], targ);
				(void) susystem(buf);
			} else {
				if (rem == -1) {
					(void) sprintf(buf, "%s -t %s",
					    cmd, targ);
					host = argv[argc - 1];
					rem = rcmd(&host, IPPORT_CMDSERVER,
					    pwd->pw_name, tuser,
					    buf, 0);
					if (rem < 0)
						exit(1);
					if (response() < 0)
						exit(1);
				}
				source(1, argv+i);
			}
		}
	} else {
		if (targetshouldbedirectory)
			verifydir(argv[argc - 1]);
		for (i = 0; i < argc - 1; i++) {
			src = colon(argv[i]);
			if (src == 0) {
				(void) sprintf(buf, "/bin/cp%s %s %s",
				    iamrecursive ? " -r" : "",
				    argv[i], argv[argc - 1]);
				(void) susystem(buf);
			} else {
				*src++ = 0;
				if (*src == 0)
					src = ".";
				suser = strrchr(argv[i], '.');
				if (suser) {
					*suser++ = 0;
					if (!okname(suser))
						continue;
				} else
					suser = pwd->pw_name;
				(void) sprintf(buf, "%s -f %s", cmd, src);
				host = argv[i];
				rem = rcmd(&host, IPPORT_CMDSERVER,
				    pwd->pw_name, suser,
				    buf, 0);
				if (rem < 0)
					exit(1);
				sink(1, argv+argc-1);
				(void) close(rem);
				rem = -1;
			}
		}
	}
	exit(errs);
}

verifydir(cp)
char *cp;
{
	struct stat stb;

	if (stat(cp, &stb) < 0)
		goto bad;
	if ((stb.st_mode & S_IFMT) == S_IFDIR)
		return;
	errno = ENOTDIR;
bad:
	error("rcp: %s: %s.\n", cp, net_error(errno));
	exit(1);
}

char *
colon(cp)
char *cp;
{

	while (*cp) {
		if (*cp == ':')
			return (cp);
		if (*cp == '/')
			return (0);
		cp++;
	}
	return (0);
}

okname(cp0)
char *cp0;
{
	register char *cp = cp0;
	register int c;

	do {
		c = *cp;
		if (c & 0200)
			goto bad;
		if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
			goto bad;
		cp++;
	} while (*cp);
	return (1);
bad:
	fprintf(stderr, "rcp: invalid user name %s\n", cp0);
	return (0);
}

susystem(buf)
char *buf;
{

	if (fork() == 0) {
		(void) setuid(getuid());
		(void) system(buf);
		_exit(0);
	} else
		(void) wait((int *)0);
}

source(argc, argv)
int argc;
char * (   (  *argv;
{
	char *last, *name;
	struct stat stb;
	char buf[BUFSIZ];
	int x, sizerr, f;
	off_t i;

	for (x = 0; x < argc; x++) {
		name = argv[x];
		if (access(name, 4) < 0 || (f = open(name, 0)) < 0) {
			error("rcp: %s: %s\n", name, net_error(errno));
			continue;
		}
		if (fstat(f, &stb) < 0)
			goto notreg;
		switch (stb.st_mode&S_IFMT) {

		case S_IFREG:
			break;

		case S_IFDIR:
			if (iamrecursive) {
				(void) close(f);
				rsource(name, (int)stb.st_mode);
				continue;
			}
			/* fall into ... */
		default:
	notreg:
			(void) close(f);
			error("rcp: %s: not a plain file\n", name);
			continue;
		}
		last = strrchr(name, '/');
		if (last == 0)
			last = name;
		else
			last++;
		(void) sprintf(buf, "C%04o %d %s\n",
		    stb.st_mode&07777, stb.st_size, last);
		(void) write(rem, buf, strlen(buf));
		if (response() < 0) {
			(void) close(f);
			continue;
		}
		sizerr = 0;
		for (i = 0; i < stb.st_size; i += BUFSIZ) {
			int amt = BUFSIZ;
			if (i + amt > stb.st_size)
				amt = stb.st_size - i;
			if (sizerr == 0 && read(f, buf, amt) != amt)
				sizerr = 1;
			(void) write(rem, buf, amt);
		}
		(void) close(f);
		if (sizerr == 0)
			ga();
		else
			error("rcp: %s: file changed size\n", name);
		(void) response();
	}
}

#include <CMC/dir.h>
struct direct *readdir();

rsource(name, mode)
char *name;
int mode;
{
	int d = opendir(name);
	char *last;
	struct direct *dp;
	char buf[BUFSIZ];
	char *bufv[1];

	if (d == 0) {
		error("%s: %s\n", name, net_error(errno));
		return;
	}
	last = strrchr(name, '/');
	if (last == 0)
		last = name;
	else
		last++;
	(void) sprintf(buf, "D%04o %d %s\n", mode&07777, 0, last);
	(void) write(rem, buf, strlen(buf));
	if (response() < 0) {
		closedir(d);
		return;
	}
	while (dp = readdir(d)) {
		if (dp->d_ino == 0)
			continue;
		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
			continue;
		if (strlen(name) + 1 + strlen(dp->d_name) >= BUFSIZ - 1) {
			error("%s/%s: Name too long.\n", name, dp->d_name);
			continue;
		}
		(void) sprintf(buf, "%s/%s", name, dp->d_name);
		bufv[0] = buf;
		source(1, bufv);
	}
	closedir(d);
	(void) write(rem, "E\n", 2);
	(void) response();
}

response()
{
	char resp, c, rbuf[BUFSIZ], *cp = rbuf;

	if (read(rem, &resp, 1) != 1)
		lostconn();
	switch (resp) {

	case 0:
		return (0);

	default:
		*cp++ = resp;
		/* fall into... */
	case 1:
	case 2:
		do {
			if (read(rem, &c, 1) != 1)
				lostconn();
			*cp++ = c;
		} while (cp < &rbuf[BUFSIZ] && c != '\n');
		if (iamremote == 0)
			(void) write(2, rbuf, cp - rbuf);
		errs++;
		if (resp == 1)
			return (-1);
		exit(1);
	}
	/*NOTREACHED*/
}

lostconn()
{

	if (iamremote == 0)
		fprintf(stderr, "rcp: lost connection\n");
	exit(1);
}

sink(argc, argv)
int argc;
char **argv;
{
	char *targ;
	char cmdbuf[BUFSIZ], nambuf[BUFSIZ], buf[BUFSIZ], *cp;
	int of, mode, wrerr, exists, first;
	off_t i, size;
	char *whopp;
	struct stat stb; 
	int targisdir = 0;
#define SCREWUP(str)    { whopp = str; goto screwup; }
	int mask = umask(0);
	char *myargv[1];

	umask(mask);
	if (argc > 1) {
		error("rcp: ambiguous target\n");
		exit(1);
	}
	targ = *argv;
	if (targetshouldbedirectory)
		verifydir(targ);
	ga();
	if (stat(targ, &stb) == 0 && (stb.st_mode & S_IFMT) == S_IFDIR)
		targisdir = 1;
	for (first = 1; ; first = 0) {
		cp = cmdbuf;
		if (read(rem, cp, 1) <= 0)
			return;
		if (*cp++ == '\n')
			SCREWUP("unexpected '\\n'");
		do {
			if (read(rem, cp, 1) != 1)
				SCREWUP("lost connection");
		} while (*cp++ != '\n');
		*cp = 0;
		if (cmdbuf[0] == '\01' || cmdbuf[0] == '\02') {
			if (iamremote == 0)
				(void) write(2, cmdbuf+1, strlen(cmdbuf+1));
			if (cmdbuf[0] == '\02')
				exit(1);
			errs++;
			continue;
		}
		*--cp = 0;
		cp = cmdbuf;
		if (*cp == 'E') {
			ga();
			return;
		}
		if (*cp != 'C' && *cp != 'D') {
			/*
                         * Check for the case "rcp remote:foo\* local:bar".
                         * In this case, the line "No match." can be returned
                         * by the shell before the rcp command on the remote is
                         * executed so the ^Aerror_message convention isn't
                         * followed.
                         */
			if (first) {
				error("%s\n", cp);
				exit(1);
			}
			SCREWUP("expected control record");
		}
		cp++;
		mode = 0;
		for (; cp < cmdbuf+5; cp++) {
			if (*cp < '0' || *cp > '7')
				SCREWUP("bad mode");
			mode = (mode << 3) | (*cp - '0');
		}
		if (*cp++ != ' ')
			SCREWUP("mode not delimited");
		size = 0;
		while (*cp >= '0' && *cp <= '9')
			size = size * 10 + (*cp++ - '0');
		if (*cp++ != ' ')
			SCREWUP("size not delimited");
		if (targisdir)
			(void) sprintf(nambuf, "%s%s%s", targ,
			    *targ ? "/" : "", cp);
		else
			(void) strcpy(nambuf, targ);
		exists = stat(nambuf, &stb) == 0;
		if (exists && access(nambuf, 2) < 0)
			goto bad2;
		{ 
			char *slash = strrchr(nambuf, '/'), *dir;
			if (slash == 0) {
				slash = "/";
				dir = ".";
			} else {
				*slash = 0;
				dir = nambuf;
			}
			if (exists == 0 && access(dir, 2) < 0)
				goto bad;
			*slash = '/';
			if (cmdbuf[0] == 'D') {
				if (stat(nambuf, &stb) == 0) {
					if ((stb.st_mode&S_IFMT) != S_IFDIR) {
						errno = ENOTDIR;
						goto bad;
					}
				} else if (mkdir(nambuf, mode) < 0)
					goto bad;
				myargv[0] = nambuf;
				sink(1, myargv);
				continue;
			}
			if ((of = creat(nambuf, mode)) < 0) {
		bad:
				*slash = '/';
		bad2:
				error("rcp: %s: %s\n", nambuf, net_error(errno));
				continue;
			}
		}
		if (exists == 0) {
			(void) stat(nambuf, &stb);
			(void) chown(nambuf, pwd->pw_uid, stb.st_gid);
			(void) chmod(nambuf, mode &~ mask);
		}
		ga();
		wrerr = 0;
		for (i = 0; i < size; i += BUFSIZ) {
			int amt = BUFSIZ;
			char *cp = buf;

			if (i + amt > size)
				amt = size - i;
			do {
				int j = read(rem, cp, amt);

				if (j <= 0)
					exit(1);
				amt -= j;
				cp += j;
			} while (amt > 0);
			amt = BUFSIZ;
			if (i + amt > size)
				amt = size - i;
			if (wrerr == 0 && write(of, buf, amt) != amt)
				wrerr++;
		}
		(void) close(of);
		(void) response();
		if (wrerr)
			error("rcp: %s: %s\n", cp, net_error(errno));
		else
			ga();
	}
screwup:
	error("rcp: protocol screwup: %s\n", whopp);
	exit(1);
}

/*VARARGS*/
error(fmt, a1, a2, a3, a4, a5)
char *fmt;
int a1, a2, a3, a4, a5;
{
	char buf[BUFSIZ], *cp = buf;

	errs++;
	*cp++ = 1;
	(void) sprintf(cp, fmt, a1, a2, a3, a4, a5);
	(void) write(rem, buf, strlen(buf));
	if (iamremote == 0)
		(void) write(2, buf+1, strlen(buf+1));
}

mkdir(name, mode)
char *name;
int mode;
{
	char *argv[4];
	int pid, rc;

	argv[0] = "mkdir";
	argv[1] = name;
	argv[2] = 0;
	pid = fork();
	if (pid < 0) {
		perror("cp");
		return (1);
	}
	if (pid) {
		while (wait(&rc) != pid)
			continue;
		if (rc == 0)
			if (chmod(name, mode) < 0) {
				perror(name);
				rc = 1;
			}
		return (rc);
	}
	(void) setuid(getuid());
	execv("/bin/mkdir", argv);
	execv("/usr/bin/mkdir", argv);
	perror("mkdir");
	_exit(1);
	/*NOTREACHED*/
}
ocket allocation failed");
		exit(1);
	}

	if (t_port == SOURCE) {
		ls_addr.sin_family = AF_INET;
		ls_addr.sin_port = 0;
		ls_addr.sin_addr.s_addr = 0;

		if (bind(t_sock, &ls_addr, sizeof(ls_addr)) < 0) {
			perunix/users/rlogin.c                                                                                    444     322     145        15024  3621344641   7733                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	Remote login -- converted from 4.2BSD
 *
 *		NOTE: this program must run setuid to ROOT
 *
 *	HISTORY:
 *
 *	Initial coding -- Pre-historic, someone at UCB
 *	Sys V conversion -- first pass by Doug Miller (CMC), Aug 1984
 *		-- finished by John Mullen (CMC), November 1984
 */


#ifndef lint
static char sccsid[] = "@(#)rlogin.c	5.0 (CMC Sys V) 11/16/84";
#endif

/*
 * rlogin - remote login
 */

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>

#include <CMC/in.h>

#include <stdio.h>
#include <termio.h>
#include <CMC/pty.h>
#include <CMC/errno.h>
#include <pwd.h>
#include <CMC/signal.h>
#include <CMC/netdb.h>

char	*strchr(), *strrchr(), *malloc(), *getenv();
struct	passwd *getpwuid();
char	*name;
int	rem;
struct	termio ttyb;
char	cmdchar = '~';
int	eight;
char	*speeds[] =
    { "0", "50", "75", "110", "134", "150", "200", "300",
      "600", "1200", "1800", "2400", "4800", "9600", "19200", "38400" };
char	term[64] = "network";
extern	int errno;
int	lostpeer();

main(argc, argv)
	int argc;
	char **argv;
{
	char *host, *cp;
	struct passwd *pwd;
	struct servent *sp;
	int uid, options = 0;

	host = strrchr(argv[0], '/');
	if (host)
		host++;
	else
		host = argv[0];
	argv++, --argc;
	if (!strcmp(host, "rlogin"))
		host = *argv++, --argc;
another:
	if (argc > 0 && !strcmp(*argv, "-d")) {
		argv++, argc--;
		options |= SO_DEBUG;
		goto another;
	}
	if (argc > 0 && !strcmp(*argv, "-l")) {
		argv++, argc--;
		if (argc == 0)
			goto usage;
		name = *argv++; argc--;
		goto another;
	}
	if (argc > 0 && !strncmp(*argv, "-e", 2)) {
		cmdchar = argv[0][2];
		argv++, argc--;
		goto another;
	}
	if (argc > 0 && !strcmp(*argv, "-8")) {
		eight = 1;
		argv++, argc--;
		goto another;
	}
	if (host == 0)
		goto usage;
	if (argc > 0)
		goto usage;
	pwd = getpwuid(getuid());
	if (pwd == 0) {
		fprintf(stderr, "Who are you?\n");
		exit(1);
	}
	sp = (struct servent *)getservbyname("login", "tcp");
	if (sp == 0) {
		fprintf(stderr, "rlogin: login/tcp: unknown service\n");
		exit(2);
	}
	cp = getenv("TERM");
	if (cp)
		strcpy(term, cp);
	if (ioctl(0, TCGETA, &ttyb)==0) {
		strcat(term, "/");
		strcat(term, speeds[ttyb.c_cflag&CBAUD]);
	}
	signal(SIGPIPE, lostpeer);
        rem = rcmd(&host, sp->s_port, pwd->pw_name,
	 (   (  	    name ? name : pwd->pw_name, term, 0);
        if (rem < 0)
                exit(1);
	if (options & SO_DEBUG &&
	    setsockopt(rem, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
		perror("rlogin: setsockopt (SO_DEBUG)");
	uid = getuid();
	if (setuid(uid) < 0) {
		perror("rlogin: setuid");
		exit(1);
	}
	doit();
	/*NOTREACHED*/
usage:
	fprintf(stderr,
	    "usage: rlogin host [ -ex ] [ -l username ] [ -8 ]\n");
	exit(1);
}

#define CRLF "\r\n"

int	child;
int	catchild();

int	tabflag;
char	deferase, defkill;

doit()
{
	int exit();

	tabflag = ttyb.c_oflag&TABDLY;
	deferase = ttyb.c_cc[VERASE];
	defkill = ttyb.c_cc[VKILL];
	signal(SIGINT, exit);
	signal(SIGHUP, exit);
	signal(SIGQUIT, exit);
	child = fork();
	if (child == -1) {
		perror("rlogin: fork");
		done();
	}
	signal(SIGINT, SIG_IGN);
	mode(1);
	if (child == 0) {
		setpgrp();
		reader();
		sleep(1);
		prf("\007Connection closed.");
		exit(3);
	}
	signal(SIGCLD, catchild);
	writer();
	prf("Closed connection.");
	done();
}

done()
{

	mode(0);
	if (child > 0 && kill(child, SIGKILL) >= 0)
		wait((int *)0);
	exit(0);
}

catchild()
{
	int status;
	int pid;

	pid = wait(&status);
	if (pid == 0)
		return;
	/*
	 * if the child (reader) dies, just quit
	 */
	if (pid < 0 || pid == child)
		done();
	signal(SIGCLD, catchild);
}

/*
 * writer: write to remote: 0 -> line.
 * ~.	terminate
 * ~^Z	suspend rlogin process.
 * ~^Y  suspend rlogin process, but leave reader alone.
 */
writer()
{
	char b[600], c;
	register char *p;
	register n;

top:
	p = b;
	for (;;) {
		int local;

		n = read(0, &c, 1);
		if (n == 0)
			break;
		if (n < 0)
			if (errno == EINTR)
				continue;
			else
				break;

		if (eight == 0)
			c &= 0177;
		/*
		 * If we're at the beginning of the line
		 * and recognize a command character, then
		 * we echo locally.  Otherwise, characters
		 * are echo'd remotely.  If the command
		 * character is doubled, this acts as a 
		 * force and local echo is suppressed.
		 */
		if (p == b)
			local = (c == cmdchar);
		if (p == b + 1 && *b == cmdchar)
			local = (c != cmdchar);
		if (!local) {
			if (write(rem, &c, 1) == 0) {
				prf("line gone");
				return;
			}
			if (eight == 0)
				c &= 0177;
		} else {
			if (c == '\r' || c == '\n') {
				char cmdc = b[1];

				if (cmdc == '.' || cmdc == '\004') {
					write(0, CRLF, sizeof(CRLF));
					return;
				}
				*p++ = c;
				write(rem, b, p - b);
				goto top;
			}
			write(1, &c, 1);
		}
		*p++ = c;
		if (c == deferase) {
			p -= 2; 
			if (p < b)
				goto top;
		}
		if (c == defkill || c == '\004' ||
		    c == '\r' || c == '\n')
			goto top;
		if (p >= &b[sizeof b])
			p--;
	}
}

oob()
{
	int out = 1+1, atmark;
	char waste[BUFSIZ], mark;
	struct termio sb;
	register n;

	ioctl(0, TCGETA, &sb);
	ioctl(1, TCFLSH, out);
	for (;;) {
		if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
			perror("ioctl");
			break;
		}
		if (atmark)
			break;
		n = read(rem, waste, sizeof (waste));
	}
	recv(rem, &mark, 1, MSG_OOB);
	if (mark & TIOCPKT_NOSTOP) {
		sb.c_iflag &= ~IXON;
		ioctl(0, TCSETA, (char *)&sb);
	}
	if (mark & TIOCPKT_DOSTOP) {
		sb.c_iflag |= IXON;
		ioctl(0, TCSETA, (char *)&sb);
	}
}

/*
 * reader: read from remote: line -> 1
 */
reader()
{
	char rb[BUFSIZ];
	register int cnt;

	signal(SIGURGENT, oob);
	{ int pid = getpid();
	  ioctl(rem, SIOCSPGRP, (char *)&pid); }
	for (;;) {
		cnt = read(rem, rb, sizeof (rb));
		if (cnt == 0)
			break;
		if (cnt < 0) {
			if (errno == EINTR)
				continue;
			break;
		}
		write(1, rb, cnt);
	}
}

mode(f)
{
	struct termio sb;

	switch (f) {

	case 0:
		sb = ttyb;
		break;

	case 1:
		sb = ttyb;
		sb.c_iflag &= ~(ICRNL);
		if ( eight )
			sb.c_iflag &= ~ISTRIP;
		sb.c_oflag &= ~(OCRNL);
		/* preserve tab delays, but turn off XTABS */
		if ((sb.c_oflag & TABDLY) == TAB3)
			sb.c_oflag &= ~TABDLY;
		sb.c_lflag &= ~(ECHO|ICANON);
		sb.c_cc[VMIN] = 1;
		sb.c_cc[VTIME] = 0;
		break;

	default:
		return;
	}
	ioctl(0, TCSETAW, (char *)&sb);
}

/*VARARGS*/
prf(f, a1, a2, a3)
	char *f;
{
	fprintf(stderr, f, a1, a2, a3);
	fprintf(stderr, CRLF);
}

lostpeer()
{
	signal(SIGPIPE, SIG_IGN);
	prf("\007Connection closed.");
	done();
}
             * followed.
                         */
			if (first) {
				error("%s\n", cp);
				exit(1);
			}
			SCREWUP("expected control record");
		}
		cp++;
		mode = 0;
		for (; cp < cmdbuf+5; cp++) {
			if (*cp < '0' || *cp > '7')
				SCREWUP("bad mode");
			mode = (mode << 3) | (*cp - '0');
		}
		if (*cp++ != ' ')
			SCREWUP("mode not delimited");
		size = 0;
		while (*cp >= '0' && *cp <= '9')
			size = size * 10 + (*cp++ - '0');
		if (*cp++ != ' ')
			SCREWUP("size not delimited")unix/users/sink.c                                                                                      444     322     145         3724  3621344641   7371                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

# include <CMC/longnames.h>
# include <fcntl.h>
# include <errno.h>
# include <stdio.h>
# include <signal.h>
# ifndef SIGCHLD
#	define SIGCHLD SIGCLD
# endif
# include <CMC/types.h>
# include <CMC/in.h>
# include <CMC/socket.h>
# include <CMC/netdb.h>

char buf[1024];
struct sockaddr_in sin = {AF_INET};

main(argc, argv)
	int argc;
	char **argv;
{
	int f, linger;
	struct sockaddr_in from;
	struct servent *sp;
	int reaper();

	sp = getservbyname("xsink", "tcp");
	if (sp == 0) {
		fprintf(stderr, "sink: tcp/xsink: unknown service\n");
		exit(1);
	}
#ifndef DEBUG
	if (fork())
		exit(0);
	setpgrp();
	for (f = 0; f < 10; f++)
		(void) close(f);
	(void) open("/", 0);
	(void) fcntl(0, F_DUPFD, 1);
	(void) fcntl(0, F_DUPFD, 2);
#endif
	sin.sin_port = sp->s_port;
	argc--, argv++;
	if (argc > 0) {
		int port = atoi(argv[0]);

		if (port < 0) {
			fprintf(stderr, "%s: bad port #\n", argv[0]);
			exit(1);
		}
		sin.sin_port = htons((u_short)port);
		argc--, argv++;
	}
	f = socket(AF_INET, SOCK_STREAM, 0);
	if (f < 0) {
		perror("sink: socket");
		exit(1);
	}
	if (bind(f, (caddr_t)&sin, sizeof (sin)) < 0) {
		perror("sink: bind");
		exit(1);
	}
	signal(SIGCHLD, reaper);
	listen(f, 10);
	for (;;) {
		int g, len = sizeof (from);

		g = accept(f, &from, &len);
		if (g < 0) {
			if (errno == EINTR)
				continue;
			perror("sink: accept");
			continue;
		}
		if (fork() == 0) {
			close(f);
			setpgrp ();
			doit(g, &from);
		}
		close(g);
	}
}

reaper ()
{
	wait (0);
	signal (SIGCHLD, reaper);
}

doit (fid, fromp)
{
	register cnt;

	for ( ; ; ) {

		cnt = read ( fid, buf, sizeof(buf));
		if ( cnt < 0 ) {
			perror ("sink read");
			exit (10);
		}

		if ( cnt == 0 )
			break;

	}
	exit (0);
}
b + 1 && *b == cmdchar)
			local = (c != cmdunix/users/rsh.c                                                                                       444     322     145         7647  3621344642   7232                                                                                                                                                                                                                                                                                                                                                                      #ifndef lint
static char sccsid[] = "@(#)rsh.c (CMC) 5.0 09/21/84";
#endif

#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <fcntl.h>
#include <sys/file.h>

#include <CMC/in.h>

#include <stdio.h>
#include <CMC/errno.h>
#include <signal.h>
#include <pwd.h>
#include <CMC/netdb.h>

/*
 * rsh - remote shell
 */
/* VARARGS */
int	error();
char	*strchr(), *strrchr(), *malloc(), *getpass(), *sprintf(), *strcpy();

struct	passwd *getpwuid();

int	errno;
int	options;
int	rfd2;
int	sendsig();

#define	mask(s)	(1 << ((s) - 1))

main(argc, argv0)
	int argc;
	char **argv0;
{
	int rem, pid;
	char *host, *cp, **ap, buf[BUFSIZ], *args, **argv = argv0, *user = 0;
	register int cc;
	int asrsh = 0;
	struct passwd *pwd;
	int readfrom, ready;
	int one = 1;
	struct servent *sp;
	int flags;

	host = strrchr(argv[0], '/');
	if (host)
		host++;
	else
		host = argv[0];
	argv++, --argc;
	if (!strcmp(host, "rsh")) {
		host = *argv++, --argc;
		asrsh = 1;
	}
another:
	if (argc > 0 && !strcmp(*argv, "-l")) {
		argv++, argc--;
		if (argc > 0)
			user = *argv++, argc--;
		goto another;
	}
	if (argc > 0 && !strcmp(*argv, "-n")) {
		argv++, argc--;
		(void) close(0);
		(void) open("/dev/null", 0);
		goto another;
	}
	if (argc > 0 && !strcmp(*argv, "-d")) {
		argv++, argc--;
		options |= SO_DEBUG;
		goto another;
	}
	/*
	 * Ignore the -e flag to allow aliases with rlogin
	 * to work
	 */
	if (argc > 0 && !strncmp(*argv, "-e", 2)) {
		argv++, argc--;
		goto another;
	}
	if (host == 0)
		goto usage;
	if (argv[0] == 0) {
		if (asrsh)
			*argv0 = "rlogin";
		execv("/usr/ucb/rlogin", argv0);
		perror("/usr/ucb/rlogin");
		exit(1);
	}
	pwd = getpwuid(getuid());
	if (pwd == 0) {
		fprintf(stderr, "who are you?\n");
		exit(1);
	}
	cc = 0;
	for (ap = argv; *ap; ap++)
		cc += strlen(*ap) + 1;
	cp = args = malloc(cc);
	for (ap = argv; *ap; ap++) {
		(void) strcpy(cp, *ap);
		while (*cp)
			cp++;
		if (ap[1])
			*cp++ = ' ';
	}
	sp = getservbyname("shell", "tcp");
	if (sp == 0) {
		fprintf(stderr, "rsh: shell/tcp: unknown service\n");
		exit(1);
	}
        rem = rcmd(&host, sp->s_port, pwd->pw_name,
		    user ? user : pwd->pw_name, args, &rfd2);
        if (rem < 0)
                exit(1);
	if (rfd2 < 0) {
		fprintf(stderr, "rsh: can't establish stderr\n");
		exit(2);
	}
	fprintf (stderr, "rsh: connected to %s\n", host);
	if (options & SO_DEBUG) {
		if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
			perror("setsockopt (stdin)");
		if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
			perror("setsockopt (stderr)");
	 (   (  }

	(void) setuid(getuid());
	signal(SIGINT, sendsig);
	signal(SIGQUIT, sendsig);
	signal(SIGTERM, sendsig);
        pid = fork();
        if (pid < 0) {
		perror("fork");
                exit(1);
        }

	flags = fcntl (rfd2, F_GETFL, 0);
	fcntl (rfd2, F_SETFL, flags | O_NDELAY);
	flags = fcntl (rem, F_GETFL, 0);
	fcntl (rem, F_SETFL, flags | O_NDELAY);

        if (pid == 0) {
		char *bp; int rembits, wc;
		(void) close(rfd2);
	reread:
		errno = 0;
		cc = read(0, buf, sizeof buf);
		if (cc <= 0)
			goto done;
		bp = buf;
	rewrite:
		wc = write(rem, bp, cc);
		if (wc < 0) {
			if (errno == EWOULDBLOCK) {
				sleep (1);
				goto rewrite;
			}
			goto done;
		}
		cc -= wc; bp += wc;
		if (cc == 0)
			goto reread;
		goto rewrite;
	done:
		(void) shutdown(rem, 1);
		exit(0);
	}

	readfrom = (1<<rfd2) | (1<<rem);
	do {
		errno = 0;
		cc = read(rfd2, buf, sizeof buf);
		if (cc <= 0) {
			if (errno != EWOULDBLOCK)
				readfrom &= ~(1<<rfd2);
		/*	else	if (readfrom == (1<<rfd2))
					break; */
		} else
			(void) write(2, buf, cc);

		errno = 0;
		cc = read(rem, buf, sizeof buf);
		if (cc <= 0) {
			if (errno != EWOULDBLOCK)
				readfrom &= ~(1<<rem);
		} else
			(void) write(1, buf, cc);
        } while (readfrom);
        (void) kill(pid, SIGKILL);
	exit(0);
usage:
	fprintf(stderr,
	    "usage: rsh host [ -l login ] [ -p passwd ] command\n");
	exit(1);
}

sendsig(signo)
	int signo;
{

	(void) write(rfd2, (char *)&signo, 1);
}
e", 2)) {
		argv++, argc--;
		goto another;
	}
	if (host == 0)
		goto usage;
	if (argv[0]unix/users/telnet.c                                                                                    444     322     145        36025  3621344643   7742                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

#ifndef lint
static char sccsid[] = "@(#)telnet.c	5.0 (CMC) 84/10/01";
#endif

/*
 * User telnet program.
 */
#include <CMC/sysdep.h>
#include <CMC/longnames.h>
#include <CMC/types.h>
#include <CMC/socket.h>
#include <fcntl.h>

#include <CMC/in.h>

#define	TELOPTS
#include <CMC/telnet.h>

#include <stdio.h>
#include <ctype.h>
#include <CMC/errno.h>
#include <signal.h>
# ifndef SIGCHLD
#	define SIGCHLD SIGCLD
# endif
#include <setjmp.h>
#include <CMC/netdb.h>
#include <termio.h>

#define CTRL(c)		('c'&037)	/* defined in ioctl.h in 4.2 */
#define	strip(x)	((x)&0177)
#define SLEEPTIME	1

char	ttyobuf[BUFSIZ], *tfrontp = ttyobuf, *tbackp = ttyobuf;
char	netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;

char	hisopts[256];
char	myopts[256];

char	doopt[] = { IAC, DO, '%', 'c', 0 };
char	dont[] = { IAC, DONT, '%', 'c', 0 };
char	will[] = { IAC, WILL, '%', 'c', 0 };
char	wont[] = { IAC, WONT, '%', 'c', 0 };

int	cncted;
int	net;
int	showoptions = 0;
int	options;
int	debug = 0;
int	crmod = 0;
char	*prompt;
char	escape = CTRL(]);

char	line[200];
int	margc;
char	*margv[20];

jmp_buf	toplevel;
jmp_buf	peerdied;

extern	int errno;

int	tn(), quit(), suspend(), bye(), help();
int	setescape(), status(), toggle(), setoptions();
int	setcrmod(), setdebug();

#define HELPINDENT (sizeof ("connect"))

struct cmd {
	char	*name;		/* command name */
	char	*help;		/* help string */
	int	(*handler)();	/* routine which executes command */
};

char	openhelp[] =	"connect to a site";
char	closehelp[] =	"close current connection";
char	quithelp[] =	"exit telnet";
char	zhelp[] =	"suspend telnet";
char	debughelp[] =	"toggle debugging";
char	escapehelp[] =	"set escape character";
char	statushelp[] =	"print status information";
char	helphelp[] =	"print help information";
char	optionhelp[] =	"toggle viewing of options processing";
char	crmodhelp[] =	"toggle mapping of received carriage returns";

struct cmd cmdtab[] = {
	{ "open",	openhelp,	tn },
	{ "connect",	openhelp,	tn },
	{ "close",	closehelp,	bye },
	{ "quit",	quithelp,	quit },
	{ "bye",	quithelp,	quit },
	{ "z",		zhelp,		suspend },
	{ "escape",	escapehelp,	setescape },
	{ "status",	statushelp,	status },
	{ "options",	optionhelp,	setoptions },
	{ "crmod",	crmodhelp,	setcrmod },
	{ "debug",	debughelp,	setdebug },
	{ "?",		helphelp,	help },
	{ "help",	helphelp,	help },
	0
};

struct sockaddr_in sin;

int	intr(), deadpeer();
char	*control();
struct	cmd *getcmd();
struct	servent *xp;

struct	termio ottyb;

main(argc, argv)
	int argc;
	char *argv[];
{
	xp = getservbyname("telnet", "tcp");
	if (xp == 0) {
		fprintf(stderr, "telnet: tcp/telnet: unknown service\n");
		exit(1);
	}
	ioctl(0, TCGETA, (char *) &ottyb);
	setbuf(stdin, 0);
	setbuf(stdout, 0);
	prompt = argv[0];
	if (argc > 1 && !strcmp(argv[1], "-d"))
		debug = SO_DEBUG, argv++, argc--;
	if (argc != 1) {
		if (setjmp(toplevel) != 0)
			exit(0);
		tn(argc, argv);
	}
	setjmp(toplevel);
	for (;;)
		command(1);
}

char	*hostname;
char	hnamebuf[32];

tn(argc, argv)
	int argc;
	char *argv[];
{
	register int c;
	register struct hostent *host;

	if (cncted) {
		printf("?Already connected to %s\n", hostname);
		return;
	}
	if (argc < 2) {
		strcpy(line, "Connect ");
		printf("(to) ");
		gets(&line[strlen(line)]);
		makeargv();
		argc = margc;
		argv = margv;
	}
	if (argc > 3) {
		printf("usage: %s host-name [port]\n", argv[0]);
		return;
	}
	host = gethostbyname(argv[1]);
	if (host) {
		sin.sin_family = host->h_addrtype;
		memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length);
		hostname = host->h_name;
	} else {
		sin.sin_family = AF_INET;
		sin.sin_addr.s_addr = inet_addr(argv[1]);
		if (sin.sin_addr.s_addr == -1) {
			printf("%s: unknown host\n", argv[1]);
			return;
		}
		strcpy(hnamebuf, argv[1]);
		hostname = hnamebuf;
	}
	sin.sin_port = xp->s_port;
	if (argc == 3) {
		sin.sin_port = atoi(argv[2]);
		if (sin.sin_port < 0) {
			printf("%s: bad port number\n", argv[2]);
			return;
		}
		sin.sin_port = htons(sin.sin_port);
	}
	net = socket(AF_INET, SOCK_STREAM, 0);
	if (net < 0) {
		perror("telnet: socket");
		return;
	}
	if (debug && setsockopt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
		perror("setsockopt (SO_DEBUG)");
	signal(SIGINT, intr);
	signal(SIGPIPE, deadpeer);
	printf("Trying...\n");
	if (connect(net, (caddr_t)&sin, sizeof (sin)) < 0) {
		perror("telnet: connect");
		signal(SIGINT, SIG_DFL);
		return;
	}
	cncted++;
	call(status, "status", 0);
	if (setjmp(peerdied) == 0)
		telnet(net);
	fprintf(stderr, "Connection closed by foreign host.\n");
	exit(1);
}

/*
 * Print status about the connection.
 */
/*VARARGS*/
status()
{
	if (cncted)
		printf("Connected to %s.\n", hostname);
	else
		printf("No connection.\n");
	printf("Escape character is '%s'.\n", control(escape));
	fflush(stdout);
}

makeargv()
{
	register char *cp;
	register char **argp = margv;

	margc = 0;
	for (cp = line; *cp;) {
		while (isspace(*cp))
			cp++;
		if (*cp == '\0')
			break;
		*argp++ = cp;
		margc += 1;
		while (*cp != '\0' && !isspace(*cp))
			cp++;
		if (*cp == '\0')
			break;
		*cp++ = '\0';
	}
	*argp++ = 0;
}

/*VARARGS*/
suspend()
{
	register int save;

	save = mode(0);
	kill(0, SIGTERM);
	/* reget parameters in case they were changed */
	ioctl(0, TCGETA, (char *) &ottyb);
	(void)  mode(save);
}

/*VARARGS*/
bye()
{
	register char *op;

	(void)  mode(0);
	if (cncted) {
		shutdown(net, 2);
		printf("Connection closed.\n");
		close(net);
		cncted = 0;
		/* reset his options */
		for (op = hisopts; op < &hisopts[256]; op++)
			*op = 0;
	}
}

/*VARARGS*/
quit()
{
	call(bye, "bye", 0);
	exit(0);
}

/*
 * Help command.
 */
help(argc, argv)
	int argc;
	char *argv[];
{
	register struct cmd *c;

	if (argc == 1) {
		printf("Commands may be abbreviated.  Commands are:\n\n");
		for (c = cmdtab; c->name; c++)
			printf("%-*s\t%s\n", HELPINDENT, c->name, c->help);
		return;
	}
	while (--argc > 0) {
		register char *arg;
		arg = *++argv;
		c = getcmd(arg);
		if (c == (struct cmd *)-1)
			printf("?Ambiguous help command %s\n", arg);
		else if (c == (struct cmd *)0)
			printf("?Invalid help command %s\n", arg);
		else
			printf("%s\n", c->help);
	}
}

/*
 * Call routine with argc, argv set from args (terminated by 0).
 * VARARGS2
 */
call(routine, args)
	int (*routine)();
	int args;
{
	register int *argp;
	register int argc;

	for (argc = 0, argp = &args; *argp++ != 0; argc++)
		;
	(*routine)(argc, &args);
}


mode(f)
	register int f;
{
/* N.B. -- EQ depends on termio structure having odd # bytes */
# define EQ(a,b) (memcmp(&a,&b,sizeof(b)-1) == 0 )

	int prevmode;
	static struct termio sb;
	static first = 1;
	static struct termio mode0, mode1, mode2;

	if ( first ) {
		first = 0;
		mode0 = ottyb;

		mode1 = ottyb;
		mode1.c_lflag &= ~ICANON;
		mode1.c_oflag &= ~TAB3;
		mode1.c_iflag &= ~ICRNL;
		mode1.c_oflag &= ~OCRNL;
		mode1.c_lflag &= ~ECHO;
		mode1.c_cc[VINTR] = -1;
		mode1.c_cc[VQUIT] = -1;
		mode1.c_cc[VERASE] = -1;
		mode1.c_cc[VKILL] = -1;
		mode1.c_cc[VEOF] = 1;	/* don't check for bursts */
		mode1.c_cc[VEOL] = 0;	/* no delay on reads */

		mode2 = mode1;
		mode2.c_iflag |= ICRNL;
		mode2.c_oflag |= OCRNL;
		mode2.c_lflag |= ECHO;
	}

	ioctl ( fileno(stdin), TCGETA, &sb );

	if ( EQ (mode0, sb) )
		prevmode = 0;
	else
	if ( EQ (mode1, sb) )
		prevmode = 1;
	else
		prevmode = 2;

	if (prevmode == f)
		return (f);

	switch (f) {

	case 0:
		sb = mode0;
		break;

	case 1:
		sb = mode1;
		break;

	case 2:
		sb = mode2;
		break;

	default:
		return;
	}
	ioctl(fileno(stdin), TCSETAF, (char *) &sb);
	return (prevmode);
}

char	sibuf[BUFSIZ], *sbp;
char	tibuf[BUFSIZ], *tbp;
int	scc, tcc;

/*
 * Select from tty and network...
 */

telnet(s)
	int s;
{
	int tin = fileno(stdin), tout = fileno(stdout);
	int pid;
	int (*ocld)();

	(void)  mode(2);
	pid = fork();
	if ( pid < 0 ) {
		perror ("telnet");
		exit (1);
	}
	if ( pid ) {		/* parent reads net, writes tty */
		ocld = signal (SIGCLD, deadpe (   (  er);
		for (;;) {
			/*
			 * Check for something to read from the network ...
			 */
			scc = read(s, sibuf, sizeof (sibuf));
			if (scc <= 0) {
				break;
			}
			sbp = sibuf;

			if (scc > 0)
				telrcv();
			if ((tfrontp - tbackp) > 0)
				ttyflush(tout);
		}
	}
	else {		/* child reads tty, writes net */
		for (;;) {

			/*
			 * Check for something to read from the tty...
			 */
			tcc = read(tin, tibuf, sizeof (tibuf));
			if (tcc <= 0) {
				break;
			}
			tbp = tibuf;

			while (tcc > 0) {
				register int c;

				if ((&netobuf[BUFSIZ] - nfrontp) < 2)
					break;
				c = *tbp++ & 0377, tcc--;
				if (strip(c) == escape) {
					command(0);
					tcc = 0;
					break;
				}
				if (c == IAC)
					*nfrontp++ = c;
				*nfrontp++ = c;
			}
			if ((nfrontp - nbackp) > 0)
				netflush(s);
		}
		exit (1);
	}
	signal (SIGCHLD, ocld);
	kill (pid, SIGTERM);
	(void) mode (0);
}

command(top)
	int top;
{
	register struct cmd *c;
	int oldmode, wasopen;

	oldmode = mode(0);
	if (!top)
		putchar('\n');
	else
		signal(SIGINT, SIG_DFL);
	for (;;) {
		printf("%s> ", prompt);
		if (gets(line) == 0) {
			if (feof(stdin)) {
				clearerr(stdin);
				putchar('\n');
			}
			break;
		}
		if (line[0] == 0)
			break;
		makeargv();
		c = getcmd(margv[0]);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			continue;
		}
		if (c == 0) {
			printf("?Invalid command\n");
			continue;
		}
		(*c->handler)(margc, margv);
		if (c->handler != help)
			break;
	}
	if (!top) {
		if (!cncted)
			longjmp(toplevel, 1);
		(void)  mode(oldmode);
	}
}

/*
 * Telnet receiver states for fsm
 */
#define	TS_DATA		0
#define	TS_IAC		1
#define	TS_WILL		2
#define	TS_WONT		3
#define	TS_DO		4
#define	TS_DONT		5

telrcv()
{
	register int c;
	static int state = TS_DATA;

	while (scc > 0) {
		c = *sbp++ & 0377, scc--;
		switch (state) {

		case TS_DATA:
			if (c == IAC) {
				state = TS_IAC;
				continue;
			}
			*tfrontp++ = c;
			/*
			 * This hack is needed since we can't set
			 * CRMOD on output only.  Machines like MULTICS
			 * like to send \r without \n; since we must
			 * turn off CRMOD to get proper input, the mapping
			 * is done here (sigh).
			 */
			if (c == '\r' && crmod)
				*tfrontp++ = '\n';
			continue;

		case TS_IAC:
			switch (c) {
			
			case WILL:
				state = TS_WILL;
				continue;

			case WONT:
				state = TS_WONT;
				continue;

			case DO:
				state = TS_DO;
				continue;

			case DONT:
				state = TS_DONT;
				continue;

			case DM:
				ioctl(fileno(stdout), TCFLSH, 2);
				break;

			case NOP:
			case GA:
				break;

			default:
				break;
			}
			state = TS_DATA;
			continue;

		case TS_WILL:
			printoption("RCVD", will, c, !hisopts[c]);
			if (!hisopts[c])
				willoption(c);
			state = TS_DATA;
			continue;

		case TS_WONT:
			printoption("RCVD", wont, c, hisopts[c]);
			if (hisopts[c])
				wontoption(c);
			state = TS_DATA;
			continue;

		case TS_DO:
			printoption("RCVD", doopt, c, !myopts[c]);
			if (!myopts[c])
				dooption(c);
			state = TS_DATA;
			continue;

		case TS_DONT:
			printoption("RCVD", dont, c, myopts[c]);
			if (myopts[c]) {
				myopts[c] = 0;
				sprintf(nfrontp, wont, c);
				nfrontp += sizeof (wont) - 2;
				printoption("SENT", wont, c);
			}
			state = TS_DATA;
			continue;
		}
	}
}

willoption(option)
	int option;
{
	char *fmt;

	switch (option) {

	case TELOPT_ECHO:
		(void)  mode(1);

	case TELOPT_SGA:
		hisopts[option] = 1;
		fmt = doopt;
		break;

	case TELOPT_TM:
		fmt = dont;
		break;

	default:
		fmt = dont;
		break;
	}
	sprintf(nfrontp, fmt, option);
	nfrontp += sizeof (dont) - 2;
	printoption("SENT", fmt, option);
}

wontoption(option)
	int option;
{
	char *fmt;

	switch (option) {

	case TELOPT_ECHO:
		(void)  mode(2);

	case TELOPT_SGA:
		hisopts[option] = 0;
		fmt = dont;
		break;

	default:
		fmt = dont;
	}
	sprintf(nfrontp, fmt, option);
	nfrontp += sizeof (doopt) - 2;
	printoption("SENT", fmt, option);
}

dooption(option)
	int option;
{
	char *fmt;

	switch (option) {

	case TELOPT_TM:
		fmt = wont;
		break;

	case TELOPT_ECHO:
		(void)  mode(2);
		fmt = will;
		hisopts[option] = 0;
		break;

	case TELOPT_SGA:
		fmt = will;
		break;

	default:
		fmt = wont;
		break;
	}
	sprintf(nfrontp, fmt, option);
	nfrontp += sizeof (doopt) - 2;
	printoption("SENT", fmt, option);
}

/*
 * Set the escape character.
 */
setescape(argc, argv)
	int argc;
	char *argv[];
{
	register char *arg;
	char buf[50];

	if (argc > 2)
		arg = argv[1];
	else {
		printf("new escape character: ");
		gets(buf);
		arg = buf;
	}
	if (arg[0] != '\0')
		escape = arg[0];
	printf("Escape character is '%s'.\n", control(escape));
	fflush(stdout);
}

/*VARARGS*/
setoptions()
{

	showoptions = !showoptions;
	printf("%s show option processing.\n", showoptions ? "Will" : "Wont");
	fflush(stdout);
}

/*VARARGS*/
setcrmod()
{

	crmod = !crmod;
	printf("%s map carriage return on output.\n", crmod ? "Will" : "Wont");
	fflush(stdout);
}

/*VARARGS*/
setdebug()
{

	debug = !debug;
	printf("%s turn on socket level debugging.\n",
		debug ? "Will" : "Wont");
	fflush(stdout);
	if (debug && net > 0 && setsockopt(net, SOL_SOCKET, SO_DEBUG, 0, 0) < 0)
		perror("setsockopt (SO_DEBUG)");
}

/*
 * Construct a control character sequence
 * for a special character.
 */
char *
control(c)
	register int c;
{
	static char buf[3];

	if (c == 0177)
		return ("^?");
	if (c >= 040) {
		buf[0] = c;
		buf[1] = 0;
	} else {
		buf[0] = '^';
		buf[1] = '@'+c;
		buf[2] = 0;
	}
	return (buf);
}

struct cmd *
getcmd(name)
	register char *name;
{
	register char *p, *q;
	register struct cmd *c, *found;
	register int nmatches, longest;

	longest = 0;
	nmatches = 0;
	found = 0;
	for (c = cmdtab; p = c->name; c++) {
		for (q = name; *q == *p++; q++)
			if (*q == 0)		/* exact match? */
				return (c);
		if (!*q) {			/* the name was a prefix */
			if (q - name > longest) {
				longest = q - name;
				nmatches = 1;
				found = c;
			} else if (q - name == longest)
				nmatches++;
		}
	}
	if (nmatches > 1)
		return ((struct cmd *)-1);
	return (found);
}

deadpeer()
{
	(void)  mode(0);
	longjmp(peerdied, -1);
}

intr()
{
	(void)  mode(0);
	longjmp(toplevel, -1);
}

ttyflush(fd)
{
	int n;

	if ((n = tfrontp - tbackp) > 0)
		n = write(fd, tbackp, n);
	if (n < 0)
		return;
	tbackp += n;
	if (tbackp == tfrontp)
		tbackp = tfrontp = ttyobuf;
}

netflush(fd)
{
	int n;

	if ((n = nfrontp - nbackp) > 0)
		n = write(fd, nbackp, n);
	if (n < 0) {
		if (errno != ENOBUFS && errno != EWOULDBLOCK) {
			(void)  mode(0);
			perror(hostname);
			close(fd);
			longjmp(peerdied, -1);
			/*NOTREACHED*/
		}
		n = 0;
	}
	nbackp += n;
	if (nbackp == nfrontp)
		nbackp = nfrontp = netobuf;
}

/*VARARGS*/
printoption(direction, fmt, option, what)
	char *direction, *fmt;
	int option, what;
{
	if (!showoptions)
		return;
	printf("%s ", direction);
	if (fmt == doopt)
		fmt = "do";
	else if (fmt == dont)
		fmt = "dont";
	else if (fmt == will)
		fmt = "will";
	else if (fmt == wont)
		fmt = "wont";
	else
		fmt = "???";
	if (option < TELOPT_SUPDUP)
		printf("%s %s", fmt, telopts[option]);
	else
		printf("%s %d", fmt, option);
	if (*direction == '<') {
		printf("\r\n");
		return;
	}
	printf(" (%s)\r\n", what ? "reply" : "don't reply");
}
c[VERASE] = -1;
		mode1.c_cc[VKILL] = -1;
		mode1.c_cc[VEOF] = 1;	/* don't check for bursts */
		mode1.c_cc[VEOL] = 0;	/* no delay on reads */

		mode2 = mode1;
		mode2.c_iflag |= ICRNL;
		mode2.c_oflag |= OCRNL;
		mode2.c_lflag |= ECHO;
	}

	ioctl ( fileno(stdin), TCGETA, &sb );

	if ( EQ (mode0, sb) )
		prevmode = 0;
	else
	if ( EQ (mode1, sb) )
		prevmode = 1;
	else
		prevmode = 2;

	if (prevmode == f)
		return (f);

	switch (f) {

	case 0:
		sb = mode0;
		break;

	case 1:
		sb = modunix/support/                                                                                          750     322     145            0  3722373234   6540                                                                                                                                                                                                                                                                                                                                                                      unix/support/README                                                                                    444     322     145         2234  3621344645   7513                                                                                                                                                                                                                                                                                                                                                                      	This directory contains tools to support downloading the ENP.

enpload:
	Utility to download the ENP.  It does this by copying files
	in S-record format to the special file /dev/enpram, and then
	causing the ENP to execute them.  See ../sys for the enpram
	device driver.  Usage is:

		enpload [-l|-x] enp0 enp_param.S enpcode.S

	where "enp0" is a magic literal, enp_param.S specifies your
	Ethernet and Internet address, and enpcode.S is the binary code
	for the ENP.

enpconfig:
	Used to produce enp_param.S which must be tailored for each host
	system.  Usage is:

		enpconfig file > enp_param.S

	where file is the configuration file for your system.  As a minimal
	sample, your file might contain:

		host "your_host_name_goes_here"
		enp your_enp_type_goes_here
		flags 0x10

	where your host name is enclosed in quotes, and your ENP number
	is the model number, such as 10 or 30.  Flags 0x10 disallows using
	the ENP console and is recommended for general operation.  For
	example, we use:

		host "cmc-cyb"
		enp 30
		flags 0x10

	The man page for enpconfig further describes the structure of
	it's input file.

	See the README file in ../../enp for further discussion.

		}
		if (line[0] == 0)
			break;
		makeargv();
		c = getcmd(margv[0]);
		if (c == (struct cmd *)-1) {
			printf("?Ambiguous command\n");
			continue;
		}
		if (c == 0) {
			printf("?Invalid command\n");
			continue;
		}
		(*c->handler)(margc, margv);
		if (c->handler != help)
			break;
	}
	if (!top) {
		if (!cncted)
			longjmp(toplevel, 1);
		(void)  m (   (  unix/support/Makefile                                                                                  444     322     145          563  3621344645  10256                                                                                                                                                                                                                                                                                                                                                                      # Make new enpconfig and enpload
# To override standard values specified in enpload, specify command line
# such as:
#	make DEFINES='-DENP_DEV=\"/dev/enpram.tcp\"'

CFLAGS = -O -I../include

all: enpload enpconfig

enpload: enpload.c
	cc -o enpload ${CFLAGS} ${DEFINES} enpload.c -lcmcnet
	chmod u+s enpload

enpconfig: enpconfig.c
	cc -o enpconfig enpconfig.c -lcmcnet

ram.S specifies your
	Ethernet and Internet address, and enpcode.S is the binary code
	for the ENP.

enpconfig:
	Used to produce enp_param.S unix/support/enpconfig.c                                                                               444     322     145        44151  3621344646  10774                                                                                                                                                                                                                                                                                                                                                                      /*
 * Build system-specific ENP parameter file.
 *
 * Usage:	enpconfig [-d] parameter_file_name
 *
 * Input is text file, one parameter per line.
 * Output (to standard out) is text file in S-record format,
 *	suitable for downloading via enpload.
 * If -d is specified, debugging output (also to stdout) dumps the
 *	table in a more readable format.
 *
 * Supported input lines are:
 *	enp	10|20|2020|30|40|44
 *	host	iaddr [eaddr]
 *	flags	number
 *	gateway	iaddr
 *	arp	iaddr eaddr
 *	laf	long_number
 *	mcast	eaddr
 *	# rest of line is comment; can appear anywhere on line
 * where
 *	iaddr ::= "host" | number
 *	eaddr ::= 1-12 hex digits (leading 0x optional)
 *	long_number ::= 1-16 hex digits (leading 0x optional)
 * and	numbers can be decimal, octal, or hex.
 *
 * The input file must have exactly one entry for each of "enp" and "host".
 * Many "arp" entries may be specified; they must have unique iaddrs.
 * "Laf" and "multicast" are supported as parameters, but the enpcode does
 *	not use them.
 *
 * The size and format of the output structure must correspond exactly to
 * that expected by the ENP code.  Expectations include:
 *	- all pointers are 4 bytes
 *	- ints and longs are 4 bytes
 *	- left-to-right bytes in a character string correspond to
 *	  increasing memory locations
 *	- the highest byte of an int or long corresponds to the
 *	  lowest address memory location
 * The subroutine which generates S-records assumes that bytes have 8
 *	bits.
 * The routines get_eaddr and get_laf store the decoded numbers in static
 *	character arrays; subsequent calls overwrite previous numbers.
 *	This will need to be changed if any commands are added which take
 *	multiple Ethernet addresses or LAF's in one command.
 *
 * 21 May 1985 - Inital coding.		Deb Brown, CMC
 */
/**/
# include <CMC/longnames.h>
# include <ctype.h>
# include <stdio.h>
# include <CMC/types.h>
# include <CMC/netdb.h>

# define EA_LTH		6	/* num bytes in ethernet address	*/
# define IA_LTH		4	/* num bytes in internet address	*/
# define LAF_LTH	8	/* num bytes in logical addr filter	*/
# define HEAPSIZE	1024
# define MAX_ARP	51
# define BSZ		25
# define LSZ		100

# define asn_eaddr(a,b)		(memcpy((a), (b), EA_LTH))
# define asn_iaddr(a,b)		(memcpy((a), (b), IA_LTH))
# define asn_laf(a,b)		(memcpy((a), (b), LAF_LTH))

# define match(s1,s2)		(!(strcmp((s1),(s2))))
# define matchn(s1,s2,n)	(!(memcmp((s1),(s2),(n))))
# define min(a,b)		((a) < (b) ? (a) : (b))

typedef	char *	IADDR;
typedef	char *	EADDR;
typedef	char *	LAF;
typedef	int	INT;

/*	ARP table structure						*/

typedef
struct arptab {
	u_char	at_iaddr[4];		/* internet address		*/
	u_char	at_enaddr[6];		/* Ethernet address		*/
	u_char	at_timer;		/* minutes since last ref	*/
	u_char	at_flags;		/* flags			*/
} ARPTAB;

/*	System Parameters Structure					*/

typedef
struct	sysparam {
	EADDR		sys_esa;	/* Node's Ethernet address	*/
	IADDR		sys_isa;	/* and Internet address		*/
	INT		sys_flags;	/* Flag bits  -  below		*/
	IADDR		sys_gateway;	/* My gateway's Internet addr	*/
	char *		sys_resv;	/* reserved			*/
	ARPTAB		*sys_arp;	/* Pre-defined ARP entries	*/
	LAF		sys_laf;	/* Logical Address Filter	*/
	EADDR		sys_mcast;	/* Multicast			*/
} SYSPARAM;

/* -------------------- G L O B A L S --------------------------------- */

struct	arptab	atab[MAX_ARP];	/* pre-defined ARP equivalences		*/
int	debug;			/* generate debugging output		*/
char	*enp_addr;		/* addr of RAM in ENP memory space	*/
char	*enp_tab;		/* where in ENP RAM to put table	*/
int	enp_set;		/* flag whether ENP has been specified	*/
FILE	*osid = stdout;		/* stream to write S-records to		*/
int	num_arp = 0;		/* num entries in arp table		*/
struct {			/* place where we build the parm table	*/
	struct sysparam	parm;
	char   heap [HEAPSIZE];
	} ptab;
char	*hp = ptab.heap;	/* ptr to next free space in heap	*/
int	num_tok;		/* number tokens on a line		*/
char	line [LSZ];		/* holds one parameter line		*/
char	cmd [BSZ],		/* command from the line		*/
	parm1 [BSZ],		/* first parameter for command		*/
	parm2 [BSZ];		/* second parameter (if any) for cmd	*/

char	*strchr ();
char	*strrchr ();
/* */
/* --------------------- C H K _ N U M _ T O K ------------------------ */
/*
 * Make sure user specified right number of fields on a parameter line
 * Usage:	chk_num_tok ((int) num);
 */

chk_num_tok (num)
int	num;
{
	if (num_tok != num)
		fatal ("Improper number of fields: %s\n", line);
}


/* -------------------- C M D _ A R P --------------------------------- */
/*
 * Add predefined ARP entry.
 * Usage:	cmd_arp (iaddr, eaddr);
 */

cmd_arp (p1, p2)
IADDR	p1;
EADDR	p2;
{
register int i;

	for (i = 0; i < num_arp; ++i)
		if (matchn (p1, atab[i].at_iaddr, IA_LTH))
			fatal ("Duplicate ARP entry for %X\n",
				*((u_long *) p1));
	asn_iaddr (atab[num_arp].at_iaddr, p1);
	asn_eaddr (atab[num_arp].at_enaddr, p2);
	if (++num_arp > MAX_ARP - 1)
		fatal ("Too many ARP entries specified\n");
}

/* -------------------- C M D _ E N P --------------------------------- */
/*
 * Set address variables based on type of ENP
 * Usage:	cmd_enp (num);
 */

cmd_enp (p1)
int	p1;
{
	if (enp_set)
		fatal ("Multiple specifications: enp\n");
	switch (p1)
	{
	case 10:	enp_addr = (char *)0xF01000;  break;
	case 20:	enp_addr = (char *)0xF01000;  break;
	case 2020:	enp_addr = (char *)0x001000;  break;
	case 30:	enp_addr = (char *)0xF01000;  break;
	case 40:	enp_addr = (char *)0x001000;  break;
	case 44:	enp_addr = (char *)0x001000;  break;
	default:
		fatal ("Unknown ENP number %d\n", p1);
	}
	enp_tab = enp_addr + 0x100;
	enp_set = 1;
}

/* -------------------- C M D _ F L A G S ----------------------------- */
/*
 * Set system flag parameter
 * Usage:	cmd_flags ((int) num);
 */

cmd_flags (p1)
int	p1;
{
	if (ptab.parm.sys_flags)
		fatal ("Multiple specifications: flags\n");
	ptab.parm.sys_flags = p1;
}

/* -------------------- C M D _ G W A Y ------------------------------- */
/*
 * Set system gateway parameter.
 * Usage:	cmd_gway (iaddr);
 */

cmd_gway (p1)
IADDR p1;
{
	if (ptab.parm.sys_gateway)
		fatal ("Multiple specifications: gateway\n");
	ptab.parm.sys_gateway = hp;
	asn_iaddr (hp, p1);
	hp += IA_LTH;
}

/* -------------------- C M D _ H O S T ------------------------------- */
/*
 * Set system Internet and (optionally) ETHERNET addresses.
 * Usage:	cmd_host (iaddr, eaddr);
 */

cmd_host (p1, p2)
IADDR	p1;
EADDR	p2;
{
	if (ptab.parm.sys_isa)
		fatal ("Multiple specifications: host\n");
	ptab.parm.sys_isa = hp;
	asn_iaddr (hp, p1);
	hp += IA_LTH;
	if (p2)
	{
		ptab.parm.sys_esa = hp;
		asn_eaddr (hp, p2);
		hp += EA_LTH;
	}
}

/* -------------------- C M D _ L A F --------------------------------- */
/*
 * Set logical address filter
 * Usage:	cmd_laf (laf);
 */

cmd_laf (p1)
LAF	p1;
{
	if (ptab.parm.sys_laf)
		fatal ("Multiple specifications: laf\n");
	ptab.parm.sys_laf = hp;
	asn_laf (hp, p1);
	hp += LAF_LTH;
}

/* -------------------- C M D _ M C A S T ----------------------------- */
/*
 * Set multicast address
 * Usage:	cmd_mcast (eaddr);
 */

cmd_mcast (p1)
EADDR	p1;
{
	if (ptab.parm.sys_mcast)
		fatal ("Multiple specifications: mcast\n");
	ptab.parm.sys_mcast = hp;
	asn_eaddr (hp, p1);
	hp += EA_LTH;
}

/* -------------------- D C D ----------------------------------------- */
/*
 * Convert a hex char to 4 binary bits
 * Usage:	num = dcd (c);
 * Returns:	-1 for invalid character
 */

dcd (c)
register char c;
{
	if (!isascii(c) || !isxdigit(c))
		return (-1);
	if (isdigit(c))
		return (c - '0');
	if (islower(c))
		return (c - 'a' + 10);
	if (isupper(c))
		return (c - 'A' + 10);
	return (-1);
}

/* -------------------- G E T _ E A D D R ------------------------------ */
/*
 * Parse a 6 digit ETHERNET address.  Number is always taken as hex; a
 * leading 0x is optional.
 *
 * Usage:	peaddr = get_eaddr (ip);
 */

EADDR
get_eaddr (ip)
char	*ip;
{
static	char obuf [EA_LTH];	/* storage for one decoded e'net addr	*/
int	lth;
EADDR	p;
EADDR	lnum ();

	lth = strlen (ip);
	p = lnum (ip, lth, obuf, EA_LTH);
	if (p == 0)
		fatal ("Too many digits in Ethernet addr: %s\n", ip);
	if (p == (char *) -1)
		fatal ("Invalid digit in Ethernet addr: %s\n", ip);
	return (p);
}

/* -------------------- G E T _ I A D D R ----------------------------- */
/*
 * Considers an input string to be a general Internet address, either
 * host name or in . notation.  Calls appropriate routine to decode,
 * depending on type.
 *
 * Usage:	iaddr = get_iaddr ((char *) s);
 */

IADDR
get_iaddr (s)
char	*s;
{
static	char obuf [IA_LTH];	/* buf for one decoded internet addr	*/
IADDR	iaddr;
IADDR	iaddr_host ();
u_long	inet_addr ();
u_long	uaddr;
register int	i;
register char	*p;

	if (*s == '"')		/* quote indicates host name		*/
	{
		if ((p =  (   (  strrchr (s, '"')) == NULL)
			fatal ("Missing ending quote on Internet address: %s\n",
				s);
		*p = 0;
		return (iaddr_host (++s));
	}
	else
	{
		if ((uaddr = inet_addr (s)) == -1)
			fatal ("Invalid Internet address: %s\n", s);
		for (i = 0; i < IA_LTH; ++i)
		{
			obuf [IA_LTH - 1 - i] = uaddr & 0xFF;
			uaddr >>= 8;
		}
		return (obuf);
	}
}

/* -------------------- G E T _ L A F --------------------------------- */
/*
 * Parse a 8 digit logical address filter.  Number is always taken as hex;
 * a leading 0x is optional.
 *
 * Usage:	laf_num = get_laf (ip);
 */

LAF
get_laf (ip)
char	*ip;
{
static	obuf [LAF_LTH];		/* storage for one decoded laf number	*/
int	lth;
char	*p;
char	*lnum();

	lth = strlen (ip);
	p = lnum (ip, lth, obuf, LAF_LTH);
	if (p == 0)
		fatal ("Too many digits in logical address filter: %s\n", ip);
	if (p == (char *) -1)
		fatal ("Invalid digit in logical address filter: %s\n", ip);
	return (p);
}

/* -------------------- F A T A L ------------------------------------- */

fatal (fmt, p1)
char *fmt;
{
	fprintf (stderr, fmt, p1);
	exit (1);
}

/* -------------------- I A D D R _ H O S T --------------------------- */
/*
 * Decode internet address given a host name.
 * Usage:	iaddr = iaddr_host (p);
 * Returns binary address.
 */

IADDR
iaddr_host (p)
char *p;
{
struct hostent *gethostbyname();
struct hostent *hep;
u_long		addr = 0;
register int	i;

	if ((hep = gethostbyname (p)) == 0)
		fatal ("Unknown host name %s\n", p);
	return (hep -> h_addr);
}

/* -------------------- L N U M --------------------------------------- */
/*
 * Decode a long hex number.
 * Usage:	ptr = lnum ((char *)ip, (int)lth, (char *)obuf, (int)olth);
 * Returns:	0 - Too many digits in input string
 *		-1 - Non-hex digit in input string
 * On return, obuf contains decoded string, two hex digits per byte, right
 *	justified in each byte.
 */

char *
lnum (ip, lth, obuf, olth)
char	*ip;			/* input ptr				*/
int	lth;			/* length of input string		*/
char	*obuf;			/* ptr to where to put results		*/
int	olth;			/* size of output buffer		*/
{
register int	shift = 0;	/* indicates left or right nibble	*/
register int	i;
register char	*op = obuf;

	if (ip[0] == '0' && (ip[1] == 'x' || ip[1] == 'X'))
	{
		ip += 2;
		lth -= 2;
	}
	if (lth > olth*2)		/* check for too long string	*/
		return ((char *)0);
	for (i = 0; i < olth; ++i)	/* zero fill decoded addr	*/
		*op++ = 0;
	--op;
	for (ip += lth; lth > 0; --lth)	/* scan back for each digit	*/
	{
		if ((i = dcd (*(--ip))) == -1)
			return ((char *)-1);
		*op += i << shift;
		shift = shift ? 0 : 4;
		if (!shift)
			--op;
	}
	return (obuf);
}

/* -------------------- M K _ P A R M --------------------------------- */
/*
 * Make complete parameter table.  Add specified ARP entries to heap.
 * Change pointers in sysparam table to point to locations in ENP
 * memory space.  Write whole thing out as S-records.
 *
 * Usage:	(void) mk_parm ();
 */

void
mk_parm ()
{
int	offset;

/* Verify user specified everything required				*/

	if (ptab.parm.sys_isa == 0)
		fatal ("ERROR: Must specify host Internet address\n");
	if (enp_set == 0)
		fatal ("ERROR: Must specify ENP model number\n");

/* If any ARP entried specified, copy table to heap			*/

	if (num_arp)
	{
		++num_arp;		/* null terminate list		*/
		ptab.parm.sys_arp = (ARPTAB *) hp;
		memcpy (hp, &(atab[0]), num_arp * sizeof(struct arptab));
		hp +=  num_arp * sizeof(struct arptab);
	}

/* Update pointer values to be in ENP memory space			*/

	offset = enp_tab - (char *)(&ptab);
	if (ptab.parm.sys_esa)
		ptab.parm.sys_esa += offset;
	if (ptab.parm.sys_isa)
		ptab.parm.sys_isa += offset;
	if (ptab.parm.sys_gateway)
		ptab.parm.sys_gateway += offset;
	if (ptab.parm.sys_arp)
		ptab.parm.sys_arp =
			(ARPTAB *) ((int) ptab.parm.sys_arp + offset);
	if (ptab.parm.sys_laf)
		ptab.parm.sys_laf += offset;
	if (ptab.parm.sys_mcast)
		ptab.parm.sys_mcast += offset;

/* Output parameter table in S-record format				*/

	if (debug)
		DUMP_PTAB ();
	mk_srec (enp_tab, &ptab, hp - (char *)(&ptab));
}

/* -------------------- M K _ S R E C --------------------------------- */
/*
 * Generate S-record output for a data buffer.
 * Usage:	(void) mk_srec (addr, buf, lth);
 *
 * Format of output:
 *	S 2 count addr data data ... csum <newline>
 * All numbers are hex.  Addr is 6 digits (3 bytes).  Count, data, and
 * csum are 2 digits each.  Count is number of bytes in record; counts
 * addr, csum, and all data.  Csum is one's complement of sum of bytes
 * in addr and all data.
 */

# define MX_SREC	16
# define MX_CLTH	MX_SREC - 4

mk_srec (addr, buf, lth)
u_long	addr;			/* download addr for first s-record	*/
char	*buf;			/* ptr to data to write			*/
int	lth;			/* number bytes to write		*/
{
u_char	csum;			/* calculated checksum			*/
int	clth;			/* length of current chunk		*/
u_long	saddr;			/* addr for current s-record		*/
int	i;

	for (; lth > 0; lth -= clth)
	{
		clth = min (MX_CLTH, lth);
		csum = clth + 4;
		fprintf (osid, "S2%02X%06X", clth+4, addr);
		for (saddr = addr, i = 0; i < 3; ++i, saddr >>= 8)
			csum += (saddr & 0xFF);
		addr += clth;
		for (i = 0; i < clth; ++i)
		{
			fprintf (osid, "%02X", (*buf) & 0xFF);
			csum += *buf++;
		}
		fprintf (osid, "%02X\n", ((~csum) & 0xFF));
	}
}
/* */
/* -------------------- M A I N --------------------------------------- */

main (argc, argv)
int	argc;
char	*argv[];
{
FILE	*isid;			/* input stream for parameter file	*/
char	*p1, *p2;
char	*file_name;
char	*prog_name;
char	c;
register int	i;

EADDR	get_eaddr ();
IADDR	get_iaddr ();

/* Check calling sequence, open input file, etc.			*/

	prog_name = argv[0];
	while ((argc > 1) && (argv[1][0] == '-'))
	{
		if (argv[1][1] == 'd')
			debug = 1;
		else
			fatal ("Unrecognized option: %s\n", argv[1]);
		--argc;
		++argv;
	}
	if (argc < 2)
		fatal ("Usage: %s [-d] filename\n", prog_name);
	file_name = argv[1];
	if ((isid = fopen (file_name, "r")) == NULL)
		fatal ("Cannot open input file %s\n", file_name);

/* Read each line.  Break it into tokens.  Process depending on command	*/

	while (1)
	{
		fgets (line, LSZ, isid);	/* read a line		*/
		if (ferror (isid))
			fatal ("Error reading file %s\n", file_name);
		if (feof (isid))
			break;
		if ((p1 = strchr (line, '#')))	/* check for comments	*/
			*p1 = '\0';
		if ((p1 = strchr (line, '\n')))	/* strip newline	*/
			*p1 = '\0';
		num_tok = sscanf (line, " %25s %25s %25s %c ",
			cmd, parm1, parm2, &c);
		if (num_tok <= 0)
			continue;

		if (match (cmd, "arp"))
		{
			chk_num_tok (3);
			cmd_arp (get_iaddr (parm1), get_eaddr (parm2));
			continue;
		}
		if (match (cmd, "enp"))
		{
			chk_num_tok (2);
			cmd_enp (atoi (parm1));
			continue;
		}
		if (match (cmd, "flags"))
		{
			chk_num_tok (2);
			cmd_flags (strtol (parm1, 0, 0));
			continue;
		}
		if (match (cmd, "gateway"))
		{
			chk_num_tok (2);
			cmd_gway (get_iaddr (parm1));
			continue;
		}
		if (match (cmd, "host"))
		{
			if (num_tok < 2 || num_tok > 3)
				fatal ("Improper number of fields: %s\n", line);
			p2 = (num_tok == 3) ? get_eaddr (parm2) : 0;
			cmd_host (get_iaddr (parm1), p2);
			continue;
		}
		if (match (cmd, "laf"))
		{
			chk_num_tok (2);
			cmd_laf (get_laf (parm1));
			continue;
		}
		if (match (cmd, "mcast"))
		{
			chk_num_tok (2);
			cmd_mcast (get_eaddr (parm1));
			continue;
		}
		fatal ("Unrecognized parameter: %s\n", line);
	}

/* Read all user's input.  Finish building table and write it out	*/

	mk_parm ();
}

/* -------------------- D U M P _ P T A B ----------------------------- */
/*
 * DUMP_* routines will dump the parameter tables.  Useful for debugging
 * when moving to new systems (with possibly different data sizes or byte
 * orders).
 */

DUMP_PTAB()
{

	printf ("sys_esa:	0x%06x\n", ptab.parm.sys_esa);
	printf ("sys_isa:	0x%06x\n", ptab.parm.sys_isa);
	printf ("sys_flags:	0x%06x\n", ptab.parm.sys_flags);
	printf ("sys_gateway:	0x%06x\n", ptab.parm.sys_gateway);
	printf ("sys_arp:	0x%06x\n", ptab.parm.sys_arp);
	printf ("sys_laf:	0x%06x\n", ptab.parm.sys_laf);
	printf ("sys_mcast:	0x%06x\n", ptab.parm.sys_mcast);

	if (ptab.parm.sys_esa) DUMP_bytes ("esa", ptab.parm.sys_esa, 6);
	if (ptab.parm.sys_isa) DUMP_long ("isa", ptab.parm.sys_isa);
	if (ptab.parm.sys_flags) DUMP_int ("flags", ptab.parm.sys_flags);
	if (ptab.parm.sys_gateway) DUMP_long ("gateway", ptab.parm.sys_gateway);
	if (ptab.parm.sys_arp) DUMP_arp ("arp", ptab.parm.sys_arp);
	if (ptab.parm.sys_laf) DUMP_bytes ("laf", ptab.parm.sys_laf, 8);
	if (ptab.parm.sys_mcast) DUMP_bytes ("mcast", ptab.parm.sys_mcast, 6);

	if (hp != ptab.heap)
		DUMP_mem (&ptab, hp-((char *) &ptab));

	printf ("\n");
}

DUMP_bytes (name, ptr, lth)
char *name;
char *ptr;
int	lth;
{
	ptr -= (enp_tab - (char *)(&ptab));
	printf ("%s:	", name);
	while (lth-- > 0)
		printf ("%02x", *(ptr++) & 0xFF);
	printf ("\n");
}

DUMP_long (name, ptr)
char *name;
u_long *ptr;
{
register char *p;

	p = (char *) ptr;
	p -= (enp_tab - (char *)(&ptab));
	ptr = (u_long *) p;
	printf ("%s:	%08X\n", name, *ptr);
}

DUMP_int (name, num)
char *name;
int num;
{
	printf ("%s:	%x\n", name, num);
}

DUMP_arp (name, ptr)
char *name;
struct arptab *ptr;
{
register int i;
register char *p;

	p = (char *) ptr;
	p -= (enp_tab - (char *)(&ptab));
	ptr = (struct arptab *) p;
	printf ("%s:", name);
	for (; *((u_long *)ptr -> at_iaddr); ++ptr)
	{
		printf ("	");
		for (i = 0; i < IA_LTH; ++i)
			printf ("%02X", (ptr -> at_iaddr [i]) & 0xFF);
		printf (" ");
		for (i = 0; i < EA_LTH; ++i)
			printf ("%02X", (ptr -> at_enaddr [i]) & 0xFF);
		printf ("\n");
	}
}

DUMP_mem (ptr, lth)
char	*ptr;
int	lth;
{
register int	i, j;
char	*addr;

	addr = (ptr + (enp_tab - (char *)(&ptab)));
	for (i = 0; i < lth; i += 16)
	{
		printf ("%06X: ", addr);
		addr += 16;
		for (j = 0; (j < 16) && (i + j < lth); ++j)
			printf ("%02X ", (ptr [i+j]) & 0xFF);
		printf ("\n");
	}
}
size = (int) atoi(*argv++);
				if ((t_size > t_maxsize) || (t_size <= 0)) {
					printf("Size?\n");
					exit(1);
				}
				break;

			case 'i':	/* Set run iteration count	*/
				argc--;
				t_count = (int) atoi(*argv++);
				break;

			case 'v':	/* Set verbose mode		*/
				r_flag |= VERBOSE;
				break;

			case 'f':	/* Using disk file		*/
				argc--;
				d_file = *argv++;
				r_flag |= DISK;
				break; (   (  unix/support/enpload.c                                                                                 644       0     145        32456  3722372505  10403                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 * This program downloads Motorola S-record format files into the ENP
 * and causes the ENP to start executing them.  It is structured to support
 * any ENP on any of the systems we know about.  The differences between
 * systems and ENPs are handled by setting various defined values described
 * below.
 *
 * Usage is:
 *	enpload [-rlag|-x] [-d device_name | enp<n>] file ...
 * where
 *	-r says reset the ENP.  No matter what the order of the
 *	   flags, the reset will be done first.
 *	-l says to load ENP but do not load transfer address
 *	-a says to load the transfer address of the last file.
 *	   -a is usually used in conjunction with -l.
 *	-g says to start the ENP.  None of the other flags start
 *	   the ENP.
 *	-x says do all of the above commands.  Cannot be used in
 *	   conjunction with any of the above 4 flags.
 *	DEFUALT: the -x flag is set which is equivelent to -rlag.
 *	         If one of the flags r,l,a,g are set the default
 *		 flag of -x is cancelled.
 *
 *	NOTE:	 The flags -l,-a and -x require a file list.  The flags
 *		 -r and -g do not.
 *
 *	-d says that the full path name is needed.  Otherwise the 
 *	   device path is specified by enp<n>. Enp<n> is exactly one
 *	   of "enp0" or "enp1"
 * There may be any number of files, all of which must be in S-record format.
 *
 * Assumptions: Bytes are at least 8 bits.
 *	Byte order between chars, ints, and longs are handled properly.
 *
 * Several values depend on the ENP being loaded, and the particular system
 * we're running on.  These values are specified as defines at compile
 * time.  These defines, and their default values are:
 *		ENP0	0x000000
 *			Host's address of first ENP.  Generally will be 0
 *			for systems which use /dev/enpram.  Systems which use
 *			/dev/kmem to access ENP memory should define ENP0 to
 *			be 0x1000 plus the base address of the ENP in the
 *			host's memory space.
 *		ENP1	0x000000
 *			Host's address of second enp (if any).  See note for
 *			ENP0.
 *		ENP_RAM	0xF01000
 *			Enp's internal RAM address plus 0x1000.
 *
 * May 6, 1985 - Modified to use S-record formats.
 *						Deb Brown, CMC
 * August 10, 1985 - Modified to take ENP device name as a parameter
 *						Deb Brown, CMC
 * May 1, 1986 - Modified to take new flags in the command line.
 *		 Allows reset and starting of ENP to be seperate
 *		 commands.
 */
/**/
#include <fcntl.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <CMC/enpram.h>

# define TRUE	-1
# define FALSE	 0
# define MXBUF	512
# define dcd(p,i)	(dcd_tab[((p)[i])&0x7F])
# define dcode(p)	((dcd(p,0) << 4) + dcd(p,1))

/* -------------------- E N P - S P E C I F I C S --------------------- */

# ifndef ENP0
#	define	ENP0	0x0		/* ENP 0's memory		*/
# endif

# ifndef ENP1
#	define	ENP1	0x0		/* ENP 1's memory		*/
# endif

# ifndef ENP_RAM
#	define	ENP_RAM	0xF01000	/* ENP's internal RAM addr	*/
# endif
/**/
/* ---------------- S T R U C T U R E S   &   T A B L E S ------------- */

/*
 *		Structure needed to read S-record file
 */

struct S_rec
{
	long	saddr;		/* where to write this info		*/
	long	scnt;		/* number of bytes to write		*/
	char	*sbuf;		/* buffer for the data			*/
};

/*
 *		ENP "device" table (so we can load multiple ENPs)
 *		See ENP/xx User Guide
*/

typedef struct	enp
{
	char	name[8];		/* Device's "name"		*/
	long	mstart;			/* Host's idea of enp mem org	*/
	char	*devfile;		/* Device file name		*/
} ENP_TAB;

ENP_TAB	enp_tab[] = {
	{ "enp0", ENP0, "/dev/enpram",},
	{ "enp1", ENP1, "/dev/enpram1",},
};

int dcd_tab [] = {
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
	0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};

/* -------------------- G L O B A L S --------------------------------- */

char		buf[MXBUF];			/* r/w buffer		*/
char		cbuf[MXBUF*2];			/* read data as chard	*/
int		dorst = 0;			/* do reset		*/
int		dold = 0;			/* doing load		*/
int		dotrn = 0;			/* do load transfer addr*/
int		dogo = 0;			/* doing go		*/
int		doall = 1;			/* assume all flags set	*/
int		xset = 0;			/* -x flag not set	*/
int		getdev = 0;			/* Get full path name	*/
unsigned long	enp_go = 0;			/* Start up vector	*/
short		enpfid = -1;			/* dev "enpram" fid	*/
FILE		*enpsid;			/* enpram as stream	*/
char		enpsbuf [BUFSIZ];		/* stream output buffer	*/
ENP_TAB		*ep;				/* enp_tab pointer	*/
char		*file_name;			/* name of current file	*/
ENP_TAB		*getenp();
int		line_num = 1;			/* line in Srec files	*/
short		num_enp = sizeof(enp_tab) / sizeof(enp_tab[0]);
char		*prog_name;			/* name of this program	*/
short int	ENP_GO = 0x8080;		/* GO command */

FILE		*fopen ();
FILE		*fdopen ();
/**/
/* -------------------- M A I N --------------------------------------- */

main( argc,argv )
int	argc;
char	**argv;
{
	register short	i;
	FILE		*in_sid;	/* stream for input file	*/
	static char	insbuf[BUFSIZ];	/* input buffer for stream	*/
	char		*enp_dev = 0;	/* device name			*/
	struct S_rec	srec;		/* struct for holding decoded S record */


/* Check for options */

	prog_name = argv[0];
	if (argc > 1) {
		++argv;
		--argc;
		while ((argv[0][0] == '-') && (argc >= 1)) {
			for(i=1;i<strlen(*argv);i++)
				switch (argv[0][i])
				{
				case 'r': dorst = 1; doall = 0; break;
				case 'l': dold = 1; doall = 0; break;
				case 'a': dotrn = 1; doall = 0; break;
				case 'g': dogo = 1; doall = 0; break;
				case 'x': xset = 1; break;
				case 'd': getdev = 1; break;
				default:
					fatal ("Unrecognized option %s\n", argv[0]);
				}	/* swith and for */
			if (--argc > 0)
				++argv;
		}
	}
	if ((!doall) && (xset)) {
		printf("Usage:  enpload [-rlag|-x] [-d device_name | enp<n>] file ...\n");
		fatal("The -x flag cannot be used with -r,-l,-a or -g\n");
	}

	if (argc < 1){
		printf("Usage:  enpload [-rlag|-x] [-d device_name | enp<n>] file ...\n");
		fatal("Must specify a device!\n");
	}

/* Check usage, that can access ENP, etc. */

	if (getdev) {
		enp_dev = *argv++;
	}
	else {
		if( (ep = getenp( *argv++ )) == 0 ) {
			printf("Usage:  enpload [-rlag|-x] [-d device_name | enp<n>] file ...\n");
			fatal("Enp<n> must be one of enp0 or enp1!\n\n");
		}
		enp_dev = ep -> devfile;
	}

	--argc;

	doall |= xset;

	if (doall) {
		dold = 1; dorst = 1; dotrn = 1; dogo = 1;
	}

	if ((dold || dotrn) && (argc < 1)){
		printf("Usage:  enpload [-rlag|-x] [-d device_name | enp<n>] file ...\n");
		fatal("Must specify files!\n");
	}

	if ((!dold) && (dotrn))
		printf("WARNING:  Loading transfer address without loading file!\n");

	if( (enpfid = open(enp_dev, O_WRONLY)) == -1 )
		fatal( "Can't access %s!\n", enp_dev );
	enpsid = fdopen (enpfid, "w");
	setbuf (enpsid, enpsbuf);


/* Reset ENP. */

	if (dorst){
		printf("\nReseting ENP ");
		reset_enp ();
		sleep(4);
		printf(" done!\n");
	}

/* Read each input file, and write it to ENP */

	if (dold) {
		printf("\nLoading S-record files ... ");
		for( i = 0; i < argc; i++ )
		{
			file_name = argv [i];
			if( (in_sid = fopen( file_name,"r" )) == NULL)
				fatal( "Can't open %s!\n",file_name );
			setbuf( in_sid, insbuf );
			if(( buf[0] = getc( in_sid )) == EOF)
				fatal( "Can't read %s!\n",file_name );
			if( buf[0] != 'S' )
				fatal( "%s not an S-record file\n",file_name );
			do_sfile( in_sid, enpfid );
			fclose( in_sid );
		}
		fflush (enpsid);
	}
	
/*	Load transfer address from last file */

	if( dotrn )
	{
		if (! dold) {		/* read transfer address from last S record*/
			file_name = argv [argc -1];
			if( (in_sid = fopen( file_name,"r" )) == NULL)
				fatal( "Can't open %s!\n",file_name );
			setbuf( in_sid, insbuf );
			if(( buf[0] = getc( in_sid )) == EOF)
				fatal( "Can't read %s!\n",file_name );
			if( buf[0] != 'S' )
				fatal( "%s not an S-record file\n",file_name );
			fseek(in_sid, (long) 0, (int) 0);
			srec.sbuf = buf;
			while (TRUE) {
				if (get_srec (in_sid,&srec) < 0)
					break;
				++line_num;
			}
			fclose(in_sid);
		}

		printf( "\nLoading ENP transfer address  %X ... ",enp_go );
		lseek(enpfid,(long) 4, 0);
		write(enpfid, &enp_go, 4);
		printf( " done!\n" );
	}
	else
		if (dogo)
			printf( "...Transfer address assumed\n" );

/*	Start ENP.  */

	if (dogo)
	{
		printf( "Starting ENP execution ... ");
		lseek(enpfid,0L,0);
		write(enpfid,&ENP_GO,2);
		printf("done!\n");
		exit(0);
	}
	else 
		printf("...ENP not started\n");
}

/* -------------------- C H K S U M ----------------------------------- */
/*
 * Calc Srec-type check sum
 * Usage:	if (chksum (cnt, ptr)) error;
 * Returns:	0 - match
 *		-1 - differ
 */

chksum (cnt, ptr)
int	cnt;
char	*ptr;
{
int	sum;
int	csum;

	if (cnt <= 0)
		return (-1);
	sum = cnt;
	csum = ptr[--cnt];
	for (; cnt-- > 0; ++ptr)
		sum += *ptr;
	if (((~sum) & 0xFF) != (csum & 0xFF))
		return (-1);
	else
		return (0);
}

/* -------------------- D C D _ A D D R ------------------------------- */
/*
 * Build a long from bytes in a char array.
 * Usage:	result = dcd_addr (buf, lth);
 */

long
dcd_addr (buf, lth)
register char	*buf;
register int	lth;
{
register long	l;

	for (l = 0; lth > 0; --lth)
		l = (l << 8) + ((*buf++) & 0xFF);
	return (l);
}

/* -------------------- D O _ S F I L E ------------------------------- */
/*
 * Download a file in  (   (  S-record format.
 *
 * Takes stream (FILE *) for input file, and file descriptor for
 * output (ENP) file.
 */

do_sfile (isid, ofid)
FILE	*isid;
int	ofid;
{
struct S_rec	srec;		/* struct for holding decoded S record */

	printf ("\n%s:\n", file_name);
	fseek (isid, (long) 0, (int) 0);	/* rewind input file */
	srec.sbuf = buf;			/* set up buf to use */
	while (TRUE)				/* read thru file */
	{
		if (get_srec (isid, &srec) < 0)
			break;
		if (dold && srec.scnt > 0)
			write_enp (ofid, srec.sbuf, srec.scnt,
			    srec.saddr - ENP_RAM + ep -> mstart);
		++ line_num;
	}
	write_enp (ofid, srec.sbuf, 0, 0);
}

/* -------------------- F A T A L ------------------------------------- */
/*
 * Print our error message and quit
 */

fatal( fmt, parm )
char	*fmt;
char	*parm;
{
	fprintf (stderr, fmt, parm);
	exit (1);
}

/* -------------------- G E T _ S R E C ------------------------------- */
/*
 * Read and decode one record from S-rec file.
 * Usage:	get_srec (isid, s_rec);
 * Returns	0 - record OK
 *		-1 - hit EOF
 * Also returns values in s_rec structure.
 * Aborts processing on any syntax error in s-record.
 */

get_srec (isid, s_rec)
FILE	*isid;
struct S_rec	*s_rec;
{
register int	cnt;		/* num bytes in record			*/
	 int	type;		/* type of addr field; 1->4 bytes, 2->6 */
	 int	sz;		/* size of addr field			*/
register int	i;

	while (((buf [0] = getc (isid)) != EOF) && buf[0] != 'S');
	if (buf[0] != 'S')		/* check for EOF		*/
		return (-1);
	if (fread (buf, sizeof (char), 3, isid) != 3) /* type and count	*/
		gsr_err ("Short line");
	type = dcd (buf,0);
	cnt = dcode (&(buf[1]));
	if (fread (cbuf, sizeof (char), 2*cnt, isid) != 2*cnt)	/* data	*/
		gsr_err ("Short data");
	for (i = 0; i < cnt; ++i)	/* convert data to binary	*/
		buf[i] = dcode (&(cbuf[2*i]));
	if (chksum (cnt, buf))		/* verify checksum		*/
		gsr_err ("Checksum");
	switch (type)
	{
	case 0:				/* Signon card; ignore it	*/
		s_rec -> scnt = 0;
		break;
	case 1:				/* data card; 4 digit address	*/
	case 2:				/* data card; 6 digit address	*/
		sz = type == 2 ? 3 : 2;
		s_rec -> saddr = dcd_addr (buf, sz);
		s_rec -> sbuf = buf + sz;
		s_rec -> scnt = cnt - 1 - sz;
		break;
	case 8:				/* "go" card; 6 digit address	*/
	case 9:				/* "go" card; 4 digit address	*/
		sz = type == 8 ? 3 : 2;
		s_rec -> scnt = 0;
		enp_go = dcd_addr (buf, sz);
		break;
	default:
		gsr_err ("Bad type");
	}
	return (0);
}

/* -------------------- G E T E N P ----------------------------------- */

ENP_TAB *
getenp( np )
register char	*np;
{
	register ENP_TAB	*ep;

	for( ep = enp_tab; ep < &enp_tab[num_enp]; ep++ )
		if( strcmp( np,ep->name ) == 0 )
			return( ep );
	return( 0 );
}

/* -------------------- G S R _ E R R --------------------------------- */

gsr_err (msg)
char	*msg;
{
	fprintf (stderr, "ERROR: %s - %s, line %d\n", msg, file_name, line_num);
	exit (1);
}

/* -------------------- R E S E T _ E N P ----------------------------- */
/*
 * Reset the ENP.
 */
reset_enp ()
{
	ioctl (enpfid, ENPIOC_RESET, 0);
}

/* -------------------- W R I T E _ E N P ----------------------------- */
/*
 * Do an (internally) buffered write to the enp.
 *
 * Takes file descriptor for ENP file, ptr to output buf, length of buf,
 * and position in the file where this buffer is to be written.
 */

write_enp (fid, buf, lth, loc)
int fid;
long lth;
char *buf;
long loc;
{
static char	my_buf [MXBUF];
static int	my_lth = 0;
static long	my_loc = 0;

	if ((loc != my_loc + my_lth) || (my_lth + lth > MXBUF))
	{
		if (my_lth)
		{
			lseek (fid, my_loc, 0);
			if (write (fid, my_buf, my_lth) != my_lth)
			{
				perror (file_name);
				exit (1);
			}
		}
		my_loc = loc;
		my_lth = 0;
	}
	if (my_lth + lth <= MXBUF)
	{
		memcpy (my_buf + my_lth, buf, lth);
		my_lth += lth;
	}
	else
	{
		lseek (fid, loc, 0);
		if (write (fid, buf, lth) != lth)
		{
			perror (file_name);
			exit (1);
		}
		my_loc = loc + lth;
	}
}
 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
	0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0unix/etc/                                                                                              750     322     145            0  3621344653   5600                                                                                                                                                                                                                                                                                                                                                                      unix/etc/README                                                                                        444     322     145         3242  3621344650   6546                                                                                                                                                                                                                                                                                                                                                                      	These files are samples of the various databases used by
the CMC Internet software.  They need to be copied to /etc in order
for the various user-level commands to operate properly.

	Following is a brief discussion of each file.  For more details
see the appropriate entry in section 5 of the manual pages included
with this distribution.

hosts:
	This file is the list of hosts known to your system.  The
copy included here is an out-of-date version of CMC's local network.
At a minimum, you will need to add an entry for each of your hosts
(including this one) to the file; it is a good idea to include the
UUCP node name of your host as one of its aliases.  Also note that
the CMC Internet software does not support the 4.2BSD notion that
host 127.1 is the local host.

hosts.equiv:
	This file is a list of host which are equivalent to this one,
in the sense that user names which are the same on the hosts refer to
the same person.  The entries in hosts.equiv must be the primary name
of the host as listed in /etc/hosts.  In order for the super-user to
to be equivalent between hosts, the hosts must be listed in /.rhosts;
see rshd(8) for a more complete discussion of .rhosts.  Note that
/etc/hosts.equiv and .rhosts are used by rsh(1), rcp(1) and rlogin(1)
only; telnet and ftp rely on /etc/passwd and/or /bin/login for user
authentication.

networks:
	A list of networks analogous to hosts.  It is an out of date
copy of an old U.C. Berkeley version.  It should be updated for your
environment and copied to /etc.

protocols:
services:
	These two files are the lists of protocols and services used
by the user-level Internet software.  They should be copied to
/etc without modification.
= 0; i < cnt; ++i)	/* convert data to binary	*/
		buf[i] = dcode (&(cbuf[2*i]));
	if (chksum (cnt, buf))		/* verify checksum		*/
		gsr_err ("Checksum");
	switch (type)
	{
	case 0:				/* Signon card; ignore it	*/
		s_rec -> scnt = 0;
		break;
	case 1:				/* data card; 4 digit address	*/
	case 2:				/* data card; 6 digit address	*/
		sz = type == 2 ?unix/etc/hosts                                                                                         444     322     145        45576  3621344651   7012                                                                                                                                                                                                                                                                                                                                                                      #
# Berkeley Host Database
#
#
#	CMC test network
#
89.0.0.84	cmc-cyb cyb chico
89.0.0.85	cmc-backboard bboard
89.0.0.89	cmc-fred fred vme
89.0.0.52	cmc-masscomp masscomp zeppo
89.0.0.0x86	cmc-yin yin
#
# Berkeley Local Net 46 -- 3Mb/s Ethernet
#
46.4		ucbarpa arpa
46.5		ucbcad cad
46.6		ucbernie ernie
46.7		ucbmonet monet
46.9		ucbesvax esvax
46.10		ucbvax ucbvax vax
46.11		ucbkim kim
46.12		ucbcalder calder
46.13		ucbdali dali
46.14		ucbmatisse matisse
46.15		ucbmedea medea
46.19		ucbingres ingres
46.20		ucboz oz
46.21		ucbear ear
46.22		ucbdegas degas
46.23		ucbturner turner
46.24		ucbmiro miro
46.25		ucbjade jade
46.26		ucbbach bach ucbstatvax statvax
#46.27		ucbic ic
46.28		ucbcory cory
46.29		ucbcartan cartan
46.30		ucbbrahms brahms ucbmathstat mathstat
#
# Berkeley Local Net 99 -- Ungermann-Bass
#
99.2.0.93	ucbmatisse-un matisse-un
99.2.0.86	ucbdali-un dali-un
#
# Berkeley Local Net 98 -- 3Com 10Mb/s Ethernet
#
98.0.2.80	ucbmatisse-ec matisse-ec
98.0.2.67	ucbmonet-ec monet-ec
#
# Berkeley Local Net 97 -- Interlan 10Mb/s Ethernet
#
97.128.1.69	ucbmonet-il monet-il
97.128.1.65	ucbmatisse-il matisse-il
#
# Berkeley Local Net 96 -- CAD 10Mb/s Ethernet
#
96.0.5.128	ucbic ic
96.0.5.129	ucbicw icw
96.0.5.130	ucbcad-ec cad-ec
#
# Berkeley Local Net 95 -- 484 Cory
#
95.0.7.70	ucbmerlin merlin
#
# Berkeley Class C Local Net 1 -- 3Mb/s Ethernet
#
192.0.46.1		ucbmatisse-en2 matisse-en2
192.0.46.2		ucbcalder-en2 calder-en2
192.0.46.3		ucbmonet-en2 monet-en2
#
# Berkeley Local Net 125 -- SUN 10Mb/s Ethernet
#
125.0.20.137	ucbmike mike
125.0.17.146	ucbrob rob
125.0.20.71	ucbchip chip
125.0.2.67	ucbkim-ec kim-ec
#
# Berkeley Local Net 89 -- Computer Center 10Mb/s Ethernet
#
89.0.4.153	ucbruby ruby Ruby ucbruby-ec ruby-ec
89.0.4.21	ucbamber amber Amber
89.0.6.38	ucbcoral coral Coral
89.0.6.35	ucbtopaz topaz Topaz
89.0.6.37	ucbivory ivory Ivory
89.0.4.119	ucblapis lapis Lapis
89.0.6.33	ucbjade-ec jade-ec
89.0.4.85	ucbpopuli populi Populi
#
# Off Campus Hosts and Networks (from SRI-NIC hostname server)
#
# DoD Internet Host Table
#  2-Jul-83
#
10.3.0.2        srinet-gateway	# gateway
10.0.0.4        utah-gateway	# gateway
10.2.0.5        bbn-ptip-gateway	# gateway
10.5.0.10       ll-gw	# gateway
10.1.0.11       stanford-gateway	# gateway
10.2.0.14       cmu-gateway	# gateway
10.3.0.17       dcn-gateway	# gateway
10.1.0.20       dcec-gateway	# gateway
10.3.0.27       isi-gateway	# gateway
10.0.0.29       brl-gateway2	# gateway
10.3.0.29       brl-gateway	# gateway
10.2.0.37       purdue-cs-gw	# gateway
10.0.0.38       bragg-gwy (   (  1	# gateway
10.1.0.49       bbn-cgtwy	# gateway
10.1.0.51       sri-c3p0	# gateway
10.3.0.51       sri-r2d2	# gateway
10.3.4.51       c3-pr-gateway	# gateway
10.1.0.54       cit-cs-gw	# gateway
10.3.0.72       bbn-net-gateway	# gateway
10.0.0.77       mit-gw	# gateway
10.3.0.80       sac-gateway	# gateway
10.3.0.91       uw-vlsi-gw	# gateway
10.0.0.94       wisc-gateway	# gateway
3.1.0.50        alta-coma
4.0.0.0         satnet
4.0.0.1         etam-expak
4.0.0.2         goonhilly-expak
4.0.0.3         tanum-expak
4.0.0.37        satnet-sink
4.0.0.40        satnet-echo
4.0.0.41        etam-monitor
4.0.0.42        goonhilly-monitor
4.0.0.43        tanum-monitor
4.0.0.62        etam-echo
4.0.0.63        goonhilly-echo
4.0.0.64        tanum-echo
4.0.0.72        raisting
4.0.0.77        raisting-echo
4.0.0.78        raisting-monitor
4.0.0.79        raisting-expak
4.0.0.88        fucino
4.0.0.93        fucino-echo
4.0.0.94        fucino-monitor
4.0.0.95        fucino-expak
8.0.0.2         bbncca bbncc
8.1.0.2         bbnccb
8.2.0.2         bbnccc
8.3.0.2         bbnccd
8.0.0.3         bbnccg
8.2.0.3         bbncc2-tac bbncc2
8.0.0.4         bbnccf
8.2.0.4         bbnccp bbnp
8.3.0.4         bbncci
8.4.0.4         bbnh rcc-unix rccu
8.0.0.5         bbn-cdnoc cdnoc
8.1.0.5         bbn-cd bbncd
8.2.0.5         bbncc1-tac bbncc1
8.1.0.6         bbn-admin admin
8.2.0.6         bbn-inoc
8.3.0.6         bbnccw bbnw
8.0.0.7         bbnccs bbns
8.1.0.7         bbnz
8.2.0.7         bbnccq bbnq
8.0.0.8         bbnccx bbnx
8.2.0.8         bbnccy bbny
8.2.0.9         bbncc3-tac bbncc3 div-5-tac div5-tac d5tac
8.0.0.10        bbncc4-tac bbncc4 div-5-tac2 d5tac-tac2 d5tac2
8.0.0.14        csnet-cic bbnj
8.1.0.14        bbn-noc bbn-nu
8.2.0.14        div6-tac d6tac div6tac
10.0.0.1        ucla-cs ucla-cecs
10.1.0.1        ucla-ccn ccn
10.2.0.1        ucla-locus ucla-security ucla-net locus
10.3.0.1        ucla-ats ats
10.0.0.2        sri-nsc11 nsc11 dnsri
10.1.0.2        sri-kl sri kl
10.2.0.2        sri-csl csl sri-csla
10.3.0.2        sri-tsc sri-tscb tscb
39.128.1.230    sri-tsc sri-tscb tscb
10.0.0.3        nosc-cc nosc
10.2.0.3        logicon
10.3.0.3        nprdc nprdc-vax nprdc-unix
10.0.0.4        utah-cs
192.5.12.21     utah-cs
10.2.0.4        utah-tac
10.3.0.4        utah-20
10.0.0.5        bbnf bbn-tenexf
3.0.0.5         bbnf bbn-tenexf
192.1.2.66      bbnf bbn-tenexf
10.1.0.5        bbng bbn-tenexg
3.1.0.5         bbng bbn-tenexg
192.1.2.67      bbng bbn-tenexg
10.3.0.5        bbna bbn
3.3.0.5         bbna bbn
192.1.2.68      bbna bbn
10.0.0.6        mit-multics multics
10.1.0.6        mit-dms dms
10.2.0.6        mit-ai-reserved
10.3.0.6        mit-ml ml
10.1.0.7        rand-relay cs-rand rand-cs occ
10.2.0.7        rand-tac
10.3.0.7        rand-unix rand-ai isd
10.0.0.8        nrl
10.1.0.8        nrl-aic
10.2.0.8        nswc-wo
10.3.0.8        nrl-tops10
10.6.0.8        nrl-arctan
10.7.0.8        nrl-css nrl-csd
10.0.0.9        harv-10 acl
10.2.0.9        yale
10.0.0.10       ll
10.1.0.10       ll-vlsi
10.2.0.10       ll-xn
10.4.0.10       ll-en
10.0.0.11       su-ai sail
36.40.0.194     su-ai sail
10.2.0.11       su-tac
10.3.0.11       su-score score
36.40.0.195     su-score score
10.0.0.12       compion-vms cc-vms dti-vms compion
10.1.0.13       gunter-adam
10.2.0.13       gunter-tac gunt
10.0.0.14       cmu-cs-b cmu-10b cmub
10.1.0.14       cmu-cs-a cmu-10a cmua
10.3.0.14       cmu-cs-c cmu-20c cmuc
10.0.0.15       rochester ur-gateway
10.0.0.16       ames-tss ames-67 ames
10.1.0.16       ames-tac
10.2.0.16       ames-vmsa
10.3.0.16       ames-vmsb ames-11
10.0.0.17       mitre
10.1.0.17       mitre-gateway mitre-gw
10.2.0.17       mitre-tac
10.4.0.17       mitre-lan
10.0.0.18       radc-multics radc
10.1.0.18       radc-psat
10.2.0.18       radc-tac radt
10.3.0.18       radc-tops20 radc-20
10.5.0.18       radc-unix
10.6.0.18       ge-crd ge
10.0.0.19       nbs-vms nbs-10 nbs
10.1.0.19       nbs-sdc
10.2.0.19       nbs-unix
10.3.0.19       nbs-pl
10.0.0.20       cctc
10.2.0.20       dcec-tac
10.3.0.20       edn-unix
10.4.0.20       dca-ems
10.5.0.20       dcec-psat
10.0.0.21       lll-tis lll-unix
10.1.0.21       lll-mfe mfe
10.2.0.21       lll-zdivision
10.0.0.22       isi-speech11
10.1.0.22       usc-isi usc-isia isia isi
10.2.0.22       usc-isic isic
10.0.0.23       usc-eclb eclb
10.1.0.23       usc-eclc eclc
10.2.0.23       usc-tac
10.3.0.23       usc-ecl ecl usc-ecla ecla
10.0.0.24       nadc
10.3.0.24       wharton-10 wharton
10.0.0.25       seismo
10.0.0.26       pentagon-tac
10.0.0.27       usc-isid isid
10.1.0.27       isi-png11 isi-xgp11
10.1.27.27      isi-png11 isi-xgp11
10.2.0.27       isi-vaxa vaxa
10.1.33.27      isi-vaxa vaxa
10.0.0.28       arpa-dms
10.1.0.28       arpa-tac1
10.2.0.28       arpa-tac2
10.3.0.28       arpa-png11 arpa-xgp11
10.0.0.29       brl
192.5.22.2      brl
10.1.0.29       apg-1
10.2.0.29       brl-tac
10.0.0.30       brooks-afb-tac afsc-hrl-tac
10.0.0.31       cca-unix cca cca-tenex
10.1.0.31       cca-vms
10.2.0.31       cca-tac cca-tip
10.0.0.32       parc-maxc parc
10.3.0.32       kestrel sci-ics sci kes sct
10.0.0.33       nps
10.2.0.33       nps-tac
10.3.0.33       fnoc-secure fnwc-secure
10.0.0.34       lbl-nmm nmm
10.1.0.34       lbl-csam lbl-unix csam
128.3.0.24      lbl-csam lbl-unix csam
10.0.0.35       nosc-secure2 usc-isir1 isir1
10.1.0.35       nosc-tecr nosc-sdl
10.2.0.35       accat-tac nelc-tip
10.3.0.35       nosc-secure3
10.4.0.35       nosc-f4
10.0.0.36       coins-tas
10.1.0.36       cincpacflt-wm
10.2.0.36       cincpac-tac
10.0.0.37       purdue purdue-cs purdue-tcp purdue-pvax pvax
128.10.0.1      purdue purdue-cs purdue-tcp purdue-pvax pvax
10.1.0.38       bragg-sta1
10.2.0.38       bragg-tac
10.0.0.40       ncc-tac
10.2.0.40       bbn-psat-ig
10.2.0.41       redstone-tac
10.0.0.43       office-1 of1
10.1.0.43       office-2 of2 office off
10.2.0.43       office-3 of3 almsa
10.3.0.43       office-7 of7 cecom
10.0.0.44       mit-xx xx
10.2.0.44       mit-tstgw
10.3.0.44       mit-mc mc
10.0.0.45       arradcom-tac
10.1.0.45       pica arradcom ardc
10.0.0.46       collins-pr
10.1.0.46       collins-gw
10.2.0.46       collins-tac
10.3.0.46       okc-unix
10.0.0.47       wpafb
10.1.0.47       wpafb-afwal avsail wpafb-afal
10.2.0.47       wpafb-tac
10.1.0.48       afwl
10.2.0.48       afwl-tac
10.0.0.49       bbnb bbn-tenexb
3.0.0.49        bbnb bbn-tenexb
10.3.0.49       bbnc bbn-tenexc
3.3.0.49        bbnc bbn-tenexc
10.4.0.49       bbn-clxx clxx
10.2.0.50       darcom-tac
10.1.1.51       sri-sta6
10.1.4.51       srijoyce joyce
10.2.0.51       sri-unix thx
10.3.1.51       sri-sta2
10.3.2.51       sri-prmh
10.0.0.52       ada-vax isi-vaxb ajpo vaxb
10.1.0.52       usc-isie isie
10.2.0.52       usc-isif isif
10.3.0.52       usc-isib isib
10.0.0.53       afsc-ad eglin
10.2.0.53       afsc-dev eglin-dev
10.3.0.53       afsc-ad-tac eglin-tac
10.4.0.53       ncsc ncsl
10.5.0.53       martin mmc
10.0.0.54       cit-20 cal-tech
10.1.0.54       cit-vax
192.5.7.2       cit-vax
10.2.0.54       acc
10.3.0.54       jpl-vax
10.1.0.55       anl-mcs
10.0.0.56       sumex-aim aim sumex
36.45.0.87      sumex-aim aim sumex
10.1.0.56       su-dsn dsn
10.2.0.56       aids-unix aids-vax aids
10.0.0.57       tycho nsa
10.1.0.57       coins-gateway coins
10.0.0.58       nyu nyu-cmcl2 cmcl2
10.1.0.58       bnl brookhaven
10.2.0.58       rutgers rutgers-20 rutgers-10 ru-red
10.2.1.58       ru-green
10.2.2.58       ru-blue
10.1.0.59       scott-tac
10.1.0.60       coradcom-tac
10.2.0.60       coradcom2-tac
10.0.0.61       stl-host1
10.1.0.61       almsa-1
10.2.0.61       stla-tac stl-tip
10.0.0.62       utexas-11
10.1.0.62       utexas-20 utexas
10.2.0.62       utexas-780
10.1.0.63       bbn-tac
10.1.0.64       martin-b mmc-b
10.2.0.64       robins-tac wralc-tac
10.3.0.64       robins-unix
10.0.0.65       afsc-sd afsd
10.1.0.65       afsc-sd-tac sd-tip
10.2.0.65       aerospace aero
10.1.0.66       afgl
10.2.0.66       afgl-tac
10.3.0.66       mitre-bedford mitre-b
10.0.0.67       afsc-hq hqafsc
10.1.0.67       afsc-hq-tac hqafsc-tac
10.0.0.68       usgs1-multics reston rest
10.2.0.68       usgs1-amdahl reston-amdahl ram
10.3.0.68       usgs1-tac
10.0.0.69       usgs2-multics denver
10.1.0.69       usgs2-tac
10.0.0.70       usgs3-multics menlo
10.1.0.70       usgs3-tac
10.2.0.70       usgs3-vms isdvms
10.2.0.71       bbn-tmp2
10.1.0.72       bbn-unix bbnu bbnccu
8.1.0.4         bbn-unix bbnu bbnccu
10.0.0.73       sri-nic nic
10.1.0.73       sri-warf warf tscf
10.2.0.73       sri-ai aic
10.3.0.73       sri-iu iuv
10.3.2.73       sri-vax sri-crvax crvax
10.4.0.73       sri-spam-test
10.0.0.74       simtel20 sands-20
10.1.0.74       wsmr70a wsmr wsmr-a wsmra
10.2.0.74       wsmr-tac
10.3.0.74       wsmr70b wsmr-b wsmrb
10.2.0.75       yuma-tac
10.3.0.75       yuma
10.1.0.77       mit-devmultics devmultics cisl
10.2.0.77       mit-tac
10.3.0.77       mit-oz oz mit-ai ai mitai
10.0.0.78       ucb-arpa
10.2.0.78       ucb-vax berkeley ucb-c70
10.3.0.78       mcclellan sacramento-unix
10.0.0.79       dec-2136
10.1.0.79       dec-marlboro dec market
10.0.0.80       hi-multics honey
10.1.0.80       sac1-tac
10.2.0.80       sac2-tac
10.0.0.81       nems
10.1.0.81       nalcon
10.2.0.81       david-tac
10.3.0.81       nsrdcoa
10.0.0.82       bbnt
8.3.0.7         bbnt
10.1.0.82       bbn-vax bbnv
8.1.0.8         bbn-vax bbnv
10.3.0.82       ddn1 ddn-1
10.4.0.82       bbn-rsm bbnr
10.6.0.82       bbn-noc2
10.0.0.83       minet-lon
10.1.0.83       minet-noc
10.2.0.83       tac-news
10.3.0.83       test-bridge
10.0.0.84       nswc-dl
10.1.0.84       nswc-g
10.2.0.84       nswc-tac
10.0.0.85       nwc-387a
10.2.0.85       nwc-tac
10.3.0.85       nwc-387b
10.0.0.86       stuttgart-tac
10.0.0.87       sandia snl
10.0.0.88       nlm-mcs nlm mcs
10.0.0.89       columbia-20 cu
10.0.0.90       lanl
10.0.0.91       washington udub uw-ward
10.2.0.91       washington-tac
10.3.0.91       uw-vlsi udub-vlsi
192.5.8.5       uw-vlsi udub-vlsi
10.2.0.92       nusc-npt
10.3.0.92       nusc
10.0.0.93       office-8 of8
10.1.0.93       office-10 darcom-ka of10
10.2.0.93       office-15 of15
10.1.0.94       uwisc csnet-sh csnetb csnet wisconsin
192.5. (   (  2.3       uwisc csnet-sh csnetb csnet wisconsin
10.0.0.95       s1-gateway
10.1.0.95       s1-a s1 s1a s-1 s1-coprolite
10.2.0.95       s1-b
10.3.0.95       s1-c s1-oz s1-vax
10.0.0.96       udel-relay ud-relay csnet-relay darcom-hq udel
10.1.0.96       udel-tcp
10.2.0.96       udel-ee
10.3.0.96       cornell
10.3.0.97       pax-rv-tac
10.0.0.98       dla-tac
10.3.0.99       uwisc-x25
14.0.0.1        purdue-tn
14.0.0.2        uwisc-tn
14.0.0.3        udel-tn
14.0.0.4        ucl-vtest
14.0.0.6        uk-satnet
14.0.0.7        uwisc-ibm
14.0.0.8        rand-tn
18.8.0.4        mit-gw-lcs
18.8.0.5        mit-bridge mit-br bridge
18.10.0.5       mit-bridge mit-br bridge
18.2.0.7        mit-br-ethernet
18.10.0.8       mit-csr csr csr2 printer mit-ln ln
18.8.0.9        mit-rts rts dssr
18.8.0.10       mit-rts40 mit-rts40-v1 rts40 rts40-v1
18.10.0.10      mit-rts40-v2 rts40-v2
18.2.0.15       mit-tiu mit-tiu1 tiu tiu1
18.2.0.21       mit-tiu mit-tiu1 tiu tiu1
18.8.0.40       mit-tiu mit-tiu1 tiu tiu1
18.9.0.128      mit-tiu mit-tiu1 tiu tiu1
18.8.0.16       mit-vax mit-vx vx
18.2.0.18       mit-alto-509 alto-509
18.2.0.20       mit-alto-510 alto-510
18.2.0.32       mit-alto-524 alto-524 guttag
18.8.0.32       mit-xx-11 mit-xx-nfe nfe xx-nfe xx-network-11
18.2.0.56       mit-alto-214b alto-214b oa-alto
18.10.0.64      mit-ajax ajax
18.10.0.65      mit-borax borax
18.10.0.66      mit-comet
18.10.0.67      mit-dutch dutch
18.10.0.68      mit-mrclean mrclean
18.10.0.69      mit-bold bold
18.10.0.70      mit-fab fab
18.10.0.71      mit-prj prj
18.2.0.72       mit-alto-511 alto-511
18.10.0.72      mit-duz duz
18.10.0.73      mit-dash dash
18.10.0.74      mit-tide tide
18.10.0.75      mit-fla fla
18.10.0.76      mit-cls cls
18.10.0.77      mit-grape-nehi grape-nehi c6
18.10.0.78      mit-heineken heineken
18.10.0.79      mit-oa oa
18.2.0.80       mit-muriel muriel
18.10.0.80      mit-macewan macewan
18.10.0.81      mit-kirin kirin
18.10.0.82      mit-molson molson
18.10.0.86      mit-milo milo
18.10.0.87      mit-opus opus
18.10.0.88      mit-rinso rinso
18.2.0.96       mit-alto-508 alto-508
18.2.0.100      mit-alto-503 alto-503
18.2.0.128      mit-spooler spooler spool
18.2.0.129      mit-np-alto np-alto
18.2.0.130      mit-alto-502 alto-502
18.2.0.134      mit-alto-828 alto-828 medg
18.2.0.170      mit-alto-520 alto-520
25.8.0.0        rsre
32.2.0.42       ucl-tac london-tac
36.45.0.85      su-ardvax ardvax
36.45.0.86      su-safe safe
36.40.0.192     su-shasta shasta
36.40.0.193     su-hnv su-diablo diablo su-hpp-ng-vax
36.40.0.203     su-navajo navajo su-na-vax
36.40.0.204     su-whitney whitney su-robotics
36.40.0.205     su-glacier glacier su-icl
36.40.0.207     su-star star
36.40.0.212     su-carmel carmel
36.40.0.213     su-sierra sierra
39.128.3.59     sri-tsca tsca
45.0.32.2       sri-spam spam
45.0.32.4       sri-rolm
47.0.32.3       sac-vax sri-spud spud
48.3.1.41       ndre1 ndre
50.0.0.8        nta-vax
128.16.9.0      ucl-sam
128.4.0.1       dcn1 linkabit
10.3.0.17       dcn1 linkabit
128.5.0.1       ford1 ford
128.5.32.1      ford-wdl1 facc
128.7.0.1       dfvlr1 dfvlr oberpfaffenhofen
128.8.0.1       umd1 umd
128.11.64.1     bbnv1
128.16.9.1      ucl-probe
128.19.1.1      edn-host1
128.20.2.1      brl-tac1
128.20.3.1      amsaa
128.4.0.2       dcn2 dcn-vax
128.5.0.2       ford2
128.5.32.2      ford-wdl2
128.7.0.2       dfvlr2
128.8.0.2       umd2 umdu umd-univac
128.10.0.2      csnet-purdue purdue-rvax rvax
128.11.0.2      bbn-cvax cvax
128.16.9.2      ucl-tg
14.0.0.5        ucl-tg
128.20.1.2      brl-hep
128.20.2.2      brl-tac2
128.20.3.2      brl-voc voc
192.5.22.1      brl-voc voc
128.4.0.3       dcn3 dcn-11a
128.5.0.3       ford3
128.5.32.3      ford-wdl3
128.7.0.3       dfvlr3
128.8.0.3       umd3
128.16.9.3      ucl-cs ucl
14.0.0.9        ucl-cs ucl
128.20.2.3      brl-tac3
128.4.0.4       dcn4 dcn-11b
128.5.0.4       ford4
128.5.32.4      ford-wdl4
128.8.0.4       cvl umd4
128.16.9.4      ucl-niftp
128.20.2.4      brl-tac4
128.20.3.4      hel-ace
128.4.0.5       dcn5 dcn-11c
128.5.32.5      ford-wdl5
128.8.0.5       umd5
128.4.0.6       dcn6 backroom
128.5.32.6      ford-wdl6
128.8.0.6       umd6
128.4.0.7       dcn7
128.7.0.7       dfvlr7 aroe stuttgart
128.8.0.7       umd7 umd-univac-test
128.4.0.8       dcn8
128.5.0.8       ford-lab ford8
128.8.0.8       umd-csd umd8
128.4.0.9       dcn9
128.5.0.9       ford-vax ford9
128.8.0.9       umd9
128.5.0.10      ford-res forda ford-20
128.8.0.10      umda umdvma
128.5.0.11      ford-ecc fordb
128.8.0.11      umdb umdvmb
128.5.0.12      ford-srl fordc
128.8.0.12      umdc umdvmc
128.5.0.13      ford-ers fordd dearborn
128.8.0.13      umdd
128.5.0.14      ford-eed forde dptc
128.8.0.14      umde
128.5.0.15      ford-foe fordf dunton
128.8.0.15      umdf
128.9.0.41      isi-elvira elvira
128.9.0.42      isi-oobgoblin hobgoblin
128.9.0.43      isi-moe moe
128.9.0.44      isi-troll troll
128.9.0.45      isi-curly curly
128.9.0.46      isi-shemp shemp
128.9.0.47      isi-zombie zombie
128.9.0.48      isi-xorn xorn
128.9.0.49      isi-750i
128.9.0.50      isi-750j
128.16.1.67     ucl-lsih
128.9.0.93      isi-iris1
128.9.0.94      isi-iris2
128.16.1.106    ucl-lsil
128.16.1.110    ucl-lsim
128.16.2.241    ucl-lsim
128.16.1.112    ucl-lsii
128.16.1.113    ucl-lsij
128.16.2.174    ucl-lsij
128.16.1.115    ucl-lsik
128.2.254.128   cmu-cs-ius
128.2.254.129   cmu-cs-vlsi
128.2.254.130   cmu-cs-ps
128.2.254.131   cmu-cs-zog
128.2.254.132   cmu-cs-g
128.2.254.133   cmu-cs-cad
128.2.254.136   cmu-cs-k
128.2.254.138   cmu-ri-fas
128.2.254.139   cmu-cs-spice
128.2.254.140   cmu-cs-gandalf
128.2.254.141   cmu-ri-leg
128.2.254.143   cmu-ri-isl
128.2.254.144   cmu-cs-j
128.2.254.145   cmu-cs-speech
128.2.254.150   cmu-cs-unh
128.2.254.151   cmu-ri-arm
128.2.254.152   cmu-ri-isl2
128.2.254.153   cmu-cs-cfs
128.2.254.154   cmu-cs-jk
128.2.254.155   cmu-cs-pt
128.2.254.156   cmu-cs-h
128.2.255.255   cmu
192.5.2.1       wisc-rsch rsch uwvax
192.5.8.1       uw-beaver beaver theodore
192.5.21.1      brl-bmd bmd70
192.5.2.2       wisc-db dbvax
192.5.8.2       uw-lumpy lumpy clarence
192.5.21.2      brl-vld vld70
192.5.7.3       cit-750
192.5.8.3       uw-wally wally
192.5.21.3      brl-svg
192.5.8.4       uw-june june
192.5.21.4      brl-tgr
192.5.15.5      nyu-cmcl1 cmcl1
192.5.8.6       uw-eddie eddie
192.5.21.6      brl-vgr vgr
128.20.1.1      brl-vgr vgr
192.5.2.7       wisc-crys crystal
192.5.15.9      nyu-acf2 nyu-ada acf2
192.5.12.22     utah-gr
192.5.12.23     utah-sp
2.0.50       darcom-tac
10.1.1.51       sri-sta6
10.1.4.51       srijoyce joyce
10.2.0.51       sri-unix thx
10.3.1.51       sri-sunix/etc/hosts.equiv                                                                                   444     322     145           46  3621344651  10041                                                                                                                                                                                                                                                                                                                                                                      cmc-cyb
cmc-masscomp
cmc-yin
cmc-fred
wisconsin
10.0.0.95       s1-gateway
10.1.0.95       s1-a s1 s1a s-1 s1-coprolite
10.2.0.95       s1-b
10.3.0.95       s1-c s1-oz s1-vax
10.0.0.96       udel-relay ud-relay csnet-relay darcom-hq udel
10.1.0.96       udel-tcp
10.2.0.96       udel-ee
10.3.0.96       cornell
10.3.0.97       pax-rv-tac
10.0.0.98       dla-tac
10.3.0.99       uwisc-x25
14.0.0.1        purdue-tn
14.0.0.2        uwisc-tn
14.0.0.3        udel-tn
14.0.0.4        ucl-vtest
14.0.0.6        uk-satnunix/etc/networks                                                                                      444     322     145         4106  3621344652   7467                                                                                                                                                                                                                                                                                                                                                                      #
# Internet networks (reordered for local efficiency)
#
ucb-ether	46		ucb ucb-localnet
ub-net		99		ungermann-bass-network
3com-net	98		3com-network
interlan-net	97		interlan-network
cad-net		96		cad-network
ucb-ether2	192.0.46	ucbether2 ether2
cc-net		89		cc-network comp-center-net
sons-net	125		three-suns-network
bbn-pr-temp     1
sf-pr-1-temp    2
bbn-rcc         3
satnet          4
demo-pr-1-temp  5
sf-pr-2-temp    6
bbn-net         8
bragg-pr-temp   9
arpanet         10
pdn             14
mit             18
mitre           23
rsre-exp        25
milnet          26
nosc-lccn       27
wideband        28
ucl-tac-net     32
rsre-null       35
su-net-temp     36
srinet-temp     39
bbn-gate-test-a 41
amprnet         44
c3-pr           45
ucb-ether       46
sac-pr-temp     47
ndre-tiu        48
nta-ring        50
rockwell-pr-temp52
bbn-test-b      128.1
cmu-net         128.2
lbl-csam        128.3
dcnet           128.4
fordnet         128.5
rutgers         128.6
dfvlr           128.7
umdnet          128.8
isi-net         128.9
purdue-cs       128.10
bbn-cronus      128.11
su-net          128.12
matnet          128.13
bbn-sat-test    128.14
s1net           128.15
uclnet          128.16
srinet          128.18
edn             128.19
brlnet          128.20
sf-pr-1         128.21
sf-pr-2         128.22
bbn-pr          128.23
rockwell-pr     128.24
bragg-pr        128.25
sac-pr          128.26
demo-pr-1       128.27
c3-pr-temp      128.28
bbn-test-c      192.0.1
bbn-fibrenet    192.1.2
cislnet         192.5.1
wisc            192.5.2
hp-design-aids  192.5.3
hp-tcg-unix     192.5.4
minet           192.5.6
cit-cs-net      192.5.7
washington      192.5.8
aeronet         192.5.9
eclnet          192.5.10
css-ring        192.5.11
utah-net        192.5.12
ccnet           192.5.13
rand-net        192.5.14
nyu-net         192.5.15
lanlland        192.5.16
nrl-net         192.5.17
uciics          192.5.19
brlnet1         192.5.21
brlnet2         192.5.22
brlnet3         192.5.23
brlnet4         192.5.24
brlnet5         192.5.25
nsrdc (   (  oa-net     192.5.26
dtnsrdc-net     192.5.27
null-net        192.5.28
	ucb ucb-localnet
ub-net		99		ungermann-bass-network
3com-net	98		3com-network
interlan-net	97		interlan-network
cad-net		96		cad-network
ucb-ether2	192.0.46	ucbether2 ether2
cc-net		89		cc-network comp-center-net
sons-net	125		three-suns-network
bbn-pr-temp     1
sf-pr-1-temp    2
bbn-rcc         3
satnet          4
demo-pr-1-temp  5
sf-pr-2-temp    6
bbn-net         8
bragg-pr-temp   9
arpanet         10
pdn             14
mit          unix/etc/protocols                                                                                     444     322     145          431  3621344652   7614                                                                                                                                                                                                                                                                                                                                                                      # derived from netinet/in.h file
# these entries should be compared to something real for verification
#			Deb Brown	CMC	9 August 1984

icmp	1	ICMP
ggp	2	GGP
tcp	6	TCP
pup	12	PUP
udp	17	UDP
nd	77	ND
raw	255	RAW	# is this really a protocol?
max	256	MAX	# is this really a protocol?
et
sons-net	125		three-suns-network
bbn-pr-temp     1
sf-pr-1-temp    2
bbn-rcc         3
satnet          4
demo-pr-1-temp  5
sf-pr-2-temp    6
bbn-net         8
bragg-pr-temp   9
arpanet         10
pdn             14
mit          unix/etc/services                                                                                      444     322     145         1760  3621344653   7442                                                                                                                                                                                                                                                                                                                                                                      # this file is derived from the info in netinet/in.h
# these	entries	should be compared to something	real for verification
#			Deb Brown	CMC	9 August 1984

# Port/socket numbers: network standard	functions

echo	7/tcp	ECHO
discard	9/tcp	DISCARD
systat	11/tcp	SYSTAT
daytime	13/tcp	DAYTIME
netstat	15/tcp	NETSTAT
ftp	21/tcp	FTP
telnet	23/tcp	TELNET
smtp	25/tcp	SMTP
time	37/tcp	TIME timeserver TIMESERVER
name	42/tcp	NAME nameserver NAMESERVER
whois	43/tcp	WHOIS
mtp	57/tcp	MTP

# Port/socket numbers: host specific functions

tftp	69/udp	TFTP
rje	77/udp	RJE
finger	79/udp	FINGER
ttylink	87/udp	TTYLINK
supdup	95/udp	SUPDUP

# UNIX TCP sockets

exec	512/tcp	EXEC execserver EXECSERVER
login	513/tcp	LOGIN loginserver LOGINSERVER
cmd	514/tcp	CMD shell SHELL cmdserver CMDSERVER
efs	520/tcp	EFS efsserver EFSSERVER
xsink	2000/tcp XSINK sink sinkserver

# UNIX UDP sockets

biff	512/udp	BIFF biffudp BIFFUDP
who	513/udp	WHO whoserver WHOSERVER
route	520/udp	ROUTE routeserver ROUTESERVER	# /* 520+1 also used */
   128.8
isi-netunix/man/                                                                                              750     322     145            0  3621344717   5601                                                                                                                                                                                                                                                                                                                                                                      unix/man/man1/                                                                                         750     322     145            0  3760705661   6440                                                                                                                                                                                                                                                                                                                                                                      unix/man/man1/ftp.1c                                                                                   444     322     145        25262  3621344655   7573                                                                                                                                                                                                                                                                                                                                                                      .TH FTP 1C "" CMC
.UC 4
.SH NAME
ftp \- file transfer program
.SH SYNOPSIS
.B ftp
[ 
.B \-v
] [
.B \-d
] [
.B \-i
] [
.B \-n
] [
.B \-g
] [
.B host
]
.SH DESCRIPTION
.I Ftp
is the user interface to the ARPANET standard File Transfer Protocol.
The program allows a user to transfer files to and from a
remote network site.
.PP
The client host with which 
.I ftp
is to communicate may be specified on the command line.
If this is done,
.I ftp
will immediately attempt to establish a connection to an FTP
server on that host; otherwise, 
.I ftp
will enter its command interpreter and await instructions
from the user.  When 
.I ftp
is awaiting commands from the user the prompt \*(lqftp>\*(rq
is provided the user.  The following commands are recognized
by
.IR ftp :
.TP
.B \&!
Invoke a shell on the local machine.
.TP
\fBappend\fP \fIlocal-file\fP [ \fIremote-file\fP ]
Append a local file to a file on the remote machine.  If
.I remote-file
is left unspecified, the local file name is used in naming the
remote file.  File transfer uses the current settings for
.IR type ,
.IR format ,
.IR mode ,
and
.IR structure .
.TP
.B ascii
Set the file transfer 
.I type
to network ASCII.  This is the default type.
.TP
.B bell
Arrange that a bell be sounded after each file transfer
command is completed.
.TP
.B binary
Set the file transfer
.I type
to support binary image transfer.
.TP
.B bye
Terminate the FTP session with the remote server
and exit
.IR ftp .
.TP
.BI cd " remote-directory"
Change the working directory on the remote machine
to 
.IR remote-directory .
.TP
.B close
Terminate the FTP session with the remote server, and
return to the command interpreter.
.TP
\fBconnect\fP \fIhost\fP [ \fIport\fP ]
A synonym for open.
.TP
.BI delete " remote-file"
Delete the file
.I remote-file
on the remote machine.
.TP
\fBdebug\fP [ \fIdebug-value\fP ]
Toggle debugging mode.  If an optional
.I debug-value
is specified it is used to set the debugging level.
When debugging is on,
.I ftp
prints each command sent to the remote machine, preceded
by the string \*(lq-->\*(rq.
.TP
\fBdir\fP [ \fIremote-directory\fP ] [ \fIlocal-file\fP ]
Print a listing of the directory contents in the
directory,
.IR remote-directory ,
and, optionally, placing the output in
.IR local-file .
If no directory is specified, the current working
directory on the remote machine is used.  If no local
file is specified, output comes to the terminal.
.TP
.BI form " format"
Set the file transfer 
.I form
to 
.IR format .
The default format is \*(lqfile\*(rq.
.TP
\fBget\fP \fIremote-file\fP [ \fIlocal-file\fP ]
Retrieve the 
.I remote-file
and store it on the local machine.  If the local
file name is not specified, it is given the same
name it has on the remote machine.
The current settings for 
.IR type ,
.IR form ,
.IR mode ,
and
.I structure
are used while transferring the file.
.TP
\fBhash\f
Toggle hash-sign (``#'') printing for each data block
transferred.  The size of a data block is 1024 bytes.
.TP
.B glob
Toggle file name globbing.  With file name globbing enabled,
each local file or pathname is processed for 
.IR csh (1)
metacharacters.  These characters include ``*?[]~{}''.
Remote files specified in mutliple item commands, e.g.
.IR mput ,
are globbed by the remote server.  With globbing disabled
all files and pathnames are treated literally.
.TP
\fBhelp\fP [ \fIcommand\fP ]
Print an informative message about the meaning of
.IR command .
If no argument is given, 
.I ftp
prints a list of the known commands.
.TP
\fBlcd\fP [ \fIdirectory\fP ]
Change the working directory on the local machine.  If
no 
.I directory
is specified, the user's home directory is used.
.TP
\fBls\fP [ \fIremote-directory\fP ] [ \fIlocal-file\fP ]
Print an abbreviated listing of the contents of a
directory on the remote machine.  If
.I remote-directory
is left unspecified, the current working directory
is used.  If no local file is specified, the output
is sent to the terminal.
.TP
\fBmdelete\fP \fIremote-files\fP
Delete the specified files on the remote machine.  If globbing
is enabled, the specification of remote files will first be
expanded using
.IR ls .
.TP
\fBmdir\fP \fIremote-files\fP \fIlocal-file\fP
Obtain a directory listing of multiple files on the remote
machine and place the result in
.IR local-file .
.TP
\fBmget\fP \fIremote-files\fP
Retrieve the specified files from the remote machine and
place them in the current local directory.  If globbing
is enabled, the specification of remote files will first be
expanding using
.IR ls .
.TP
\fBmkdir\fP \fIdirectory-name\fP
Make a directory on the remote machine.
.TP
\fBmls\fP \fIremote-files\fP \fIlocal-file\fP
Obtain an abbreviated listing of multiple files on the remote
machine and place the result in
.IR local-file .
.TP
\fBmode\fP [ \fImode-name\fP ]
Set the file transfer
.I mode
to
.IR mode-name .
The default mode is \*(lqstream\*(rq mode.
.TP
\fBmput\fP \fIlocal-files\fP
Transfer multiple local files from the current local directory
to the current working directory on the remote machine.
.TP
\fBopen\fP \fIhost\fP [ \fIport\fP ]
Establish a connection to the specified
.I host
FTP server.  An optional port number may be supplied,
in which case, 
.I ftp
will attempt to contact an FTP server at that port.
If the 
.I auto-login
option is on (default), 
.I ftp
will also attempt to automatically log the user in to
the FTP server (see below).
.TP
.B prompt
Toggle interactive prompting.  Interactive prompting
occurs during multiple file transfers to allow the
user to selectively retrieve or store files.  If
prompting is turned off (default), any
.I mget
or
.I mput
wi (   (  ll transfer all files.
.TP
\fBput\fP \fIlocal-file\fP [ \fIremote-file\fP ]
Store a local file on the remote machine.  If 
.I remote-file
is left unspecified, the local file name is used
in naming the remote file.  File transfer uses the
current settings for
.IR type ,
.IR format ,
.IR mode ,
and
.IR structure .
.TP
.B pwd
Print the name of the current working directory on the remote
machine.
.TP
.B quit
A synonym for bye.
.TP
.BI quote " arg1 arg2 ..."
The arguments specified are sent, verbatim, to the remote FTP
server.  A single FTP reply code is expected in return.
.TP
\fBrecv\fP \fIremote-file\fP [ \fIlocal-file\fP ]
A synonym for get.
.TP
\fBremotehelp\fP [ \fIcommand-name\fP ]
Request help from the remote FTP server.  If a 
.I command-name
is specified it is supplied to the server as well.
.TP
\fBrename\fP [ \fIfrom\fP ] [ \fIto\fP ]
Rename the file
.I from
on the remote machine, to the file
.IR to .
.TP
.BI rmdir " directory-name"
Delete a directory on the remote machine.
.TP
\fBsend\fP \fIlocal-file\fP [ \fIremote-file\fP ]
A synonym for put.
.TP
.B sendport
Toggle the use of PORT commands.  By default, 
.I ftp
will attempt to use a PORT command when establishing
a connection for each data transfer.  If the PORT
command fails, 
.I ftp
will use the default data port.  When the use of PORT
commands is disabled, no attempt will be made to use
PORT commands for each data transfer.  This is useful
for certain FTP implementations which do ignore PORT
commands but, incorrectly, indicate they've been accepted.
.TP
.B status
Show the current status of
.IR ftp .
.TP
\fBstruct\fP [ \fIstruct-name\fP ]
Set the file transfer
.I structure
to
.IR struct-name .
By default \*(lqstream\*(rq structure is used.
.TP
.B tenex
Set the file transfer type to that needed to
talk to TENEX machines.
.TP
.B trace
Toggle packet tracing.
.TP
\fBtype\fP [ \fItype-name\fP ]
Set the file transfer
.I type
to
.IR type-name .
If no type is specified, the current type
is printed.  The default type is network ASCII.
.TP
\fBuser\fP \fIuser-name\fP [ \fIpassword\fP ] [ \fIaccount\fP ]
Identify yourself to the remote FTP server.  If the
password is not specified and the server requires it,
.I ftp
will prompt the user for it (after disabling local echo).
If an account field is not specified, and the FTP server
requires it, the user will be prompted for it.  Unless
.I ftp
is invoked with \*(lqauto-login\*(rq disabled, this
process is done automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, all responses from
the FTP server are displayed to the user.  In addition,
if verbose is on, when a file transfer completes, statistics
regarding the efficiency of the transfer are reported.  By default,
verbose is on.
.TP
\fB?\fP [ \fIcommand\fP ]
A synonym for help.
.PP
Command arguments which have embedded spaces may be quoted with
double quote (") marks.
.SH "FILE NAMING CONVENTIONS"
Files specified as arguments to
.I ftp
commands are processed according to the following rules.
.TP
1)
If the file name \*(lq\-\*(rq is specified, the
.B stdin
(for reading) or
.B stdout
(for writing) is used.
.TP
2)
If the first character of the file name is \*(lq|\*(rq, the
remainder of the argument is interpreted as a shell command.
.I Ftp
then forks a shell, using 
.IR popen (3)
with the argument supplied, and reads (writes) from the stdout
(stdin).  If the shell command includes spaces, the argument
must be quoted; e.g. \*(lq"| ls -lt"\*(rq.  A particularly
useful example of this mechanism is: \*(lqdir |more\*(rq.
.TP
3)
Failing the above checks, if ``globbing'' is enabled, 
local file names are expanded
according to the rules used in the 
.IR csh (1);
c.f. the 
.I glob
command. 
.SH "FILE TRANSFER PARAMETERS"
The FTP specification specifies many parameters which may
affect a file transfer.  The 
.I type
may be one of \*(lqascii\*(rq, \*(lqimage\*(rq (binary),
\*(lqebcdic\*(rq, and \*(lqlocal byte size\*(rq (for PDP-10's
and PDP-20's mostly).
.I Ftp
supports the ascii and image types of file transfer.
.PP
.I Ftp
supports only the default values for the remaining
file transfer parameters: 
.IR mode ,
.IR form ,
and
.IR struct .
.SH OPTIONS
Options may be specified at the command line, or to the 
command interpreter.
.PP
The
.B \-v
(verbose on) option forces
.I ftp
to show all responses from the remote server, as well
as report on data transfer statistics.
.PP
The
.B \-n
option restrains 
.I ftp
from attempting \*(lqauto-login\*(rq upon initial connection.
If auto-login is enabled, 
.I ftp
will check the
.I .netrc
file in the user's home directory for an entry describing
an account on the remote machine.  If no entry exists,
.I ftp
will use the login name on the local machine as the user
identity on the remote machine, and prompt for a password
and, optionally, an account with which to login.
.PP
The
.B \-i
option turns off interactive prompting during
mutliple file transfers.
.PP
The
.B \-d
option enables debugging.
.PP
The
.B \-g
option disables file name globbing.
.SH BUGS
Many FTP server implementation do not support the experimental
operations such as print working directory.
.PP
Aborting a file
transfer does not work right; if one attempts this the local
.I ftp
will likely have to be killed by hand.
is on (default), 
.I ftp
will also attempt to automatically log the user in to
the FTP server (see below).
.TP
.B prompt
Toggle interactive prompting.  Interactive prompting
occurs during multiple file transfers to allow the
user to selectively retrieve or store files.  If
prompting is turned off (default), any
.I mget
or
.I mput
wiunix/man/man1/ntest.1c                                                                                 444     322     145         3735  3621344656  10121                                                                                                                                                                                                                                                                                                                                                                      .TH NTEST 1C "" CMC
.SH NAME
ntest - canonical "user" process for testing network
.SH SYNOPSIS
.B ntest
\fBrecv\fR|\fBsend\fR|\fBecho\fR
.RB [ -h
host]
.RB [ -s
size]
.RB [ -i
count]
.br
.RB [ -f
file]
.RB [ -p
\fBe\fR|\fBu\fR|\fBi\fR|\fBt\fR]
[\fB-l\fR]
[\fB-v\fR]
.SH DESCRIPTION
.I Ntest
exercises communication over the network.
A total of
.I count
packets of
.I size
bytes will be sent to (\fBsend\fR) or received from (\fBrecv\fR)
the specified host.
At the completion of the transfer, information is displayed about the
data rates observed and about the last packet transferred.
.PP
The
.B cal
option is used to calibrate overhead rates for
.IR ntest .
It computes data rates for
.I ntest
for reading a disk file, writing an internal buffer to /dev/null,
and reading a disk file and writing it to /dev/null.
.PP
One of
.BR recv ,
.BR send ,
or
.B cal
must be supplied.
Other parameters have default options:
.TP
.B -f
The specified
.I file
will be used as the data source or sink.
If \fB-f\fR is not specified, the transferred data is discarded.
.TP
.B -h
Default is the test host "bboard".
.TP
.B -i
Default iterations is 1000.
.TP
.B -l
Loop.
Repeat the test forever.
.TP
.B -p
Communication is normally at the TCP level.
This option specifies an alternate protocol is to be used.
Supported protocols are:
.RS 10
.TP
.B e
Use raw Ethernet
.TP
.B i
Use raw Internet
.TP
.B t
Use TCP
.TP
.B u
Use UDP
.RE
.TP
.B -s
Default package size is 1024.
.TP
.B -v
Display packets at the end of a test run, showing
last sent or last received packet, with an attempt at decoding the packet
header.
.PP
Addresses for hosts known to
.I ntest
are hardcoded to allow testing hosts which are not
in the /etc/hosts file.
.PP
Usage is generally to run an
.I ntest
.B send
on one system and an
.I ntest
.B recv
on another to test communication between the two.
.SH CAVEAT
.I Ntest
uses its own built-in host table rather than /etc/hosts.
You will need to add your hosts to the table in
.I ntest
in order to use this program.
k ASCII.
.TP
\fBuser\fP \fIuser-namunix/man/man1/rcp.1c                                                                                   444     322     145         3315  3621344656   7542                                                                                                                                                                                                                                                                                                                                                                      .TH RCP 1C "" CMC
.UC 4
.SH NAME
rcp \- remote file copy
.SH SYNOPSIS
.B rcp
file1 file2
.br
.B rcp
[
.B \-r
] file ... directory
.SH DESCRIPTION
.I Rcp
copies files between machines.  Each
.I file
or
.I directory
argument is either a remote file name of the
form ``rhost:path'', or a local file name (containing no `:' characters,
or a `/' before any `:'s.)
.PP
If the
.B \-r
is specified and any of the source files are directories,
.I rcp
copies each subtree rooted at that name; in this case
the destination must be a directory.
.PP
If
.I path
is not a full path name, it is interpreted relative to
your login directory on 
.IR rhost .
A 
.I path
on a remote host may be quoted (using \e, ", or \(aa)
so that the metacharacters are interpreted remotely.
.PP
.I Rcp
does not prompt for passwords; your current local user name
must exist on
.I rhost
and allow remote command execution via
.IR rsh (1C).
.PP
.I Rcp
handles third party copies, where neither source nor target files
are on the current machine.
Hostnames may also take the form ``rhost.rname'' to use
.I rname
rather than the current user name on the remote host.
.SH FILES
/etc/hosts.equiv (on remote host)
.br
$HOME/.rhosts (on remote host)
.SH SEE ALSO
ftp(1C), rsh(1C), rlogin(1C), cp(1)
.SH BUGS
Doesn't detect all cases where the target of a copy might
be a file in cases where only a directory should be legal.
.PP
Is confused by any output generated by commands in a
\&.login, \&.profile, or \&.cshrc file on the remote host.
.PP
The 
.B \-r
option depends on
.IR (   (   cp (1)
in order to work.
In particular, "vanilla" System V
.I cp
does not handle
.IR -r .
This will affect 
.I rcp -r
only in the case where both the source and target directory are on the
local machine.
irectory
argument is either a remote file name of the
form ``rhost:path'', or a local file name (containing no `:' characters,
or a `/' before any `:'s.)
.PP
If the
.B \-r
is specified and any of the source files are directories,
.I rcp
copies each subtree rooted at that name; in this case
the destination unix/man/man1/rlogin.1c                                                                                444     322     145         4254  3621344657  10254                                                                                                                                                                                                                                                                                                                                                                      .TH RLOGIN 1C "" "CMC 2.0"
.UC 4
.SH NAME
rlogin \- remote login
.SH SYNOPSIS
.B rlogin
rhost [
\fB\-e\fR\fI\|c\fR
] [
.B \-l
username ]
.br
rhost [
\fB\-e\fR\fIc\fR
] [
.B \-l
username ]
.SH DESCRIPTION
.I Rlogin
connects your terminal on the current local host system
.I lhost
to the remote host system
.I rhost.
.PP
Each host has a file
.I /etc/hosts.equiv
which contains a list of \fIrhost\fR's with which it shares account names.
(The host names must be the standard names as described in
.IR rsh (1C).)
When you
.I rlogin
as the same user on an equivalent host, you don't need
to give a password.
Each user may also have a private equivalence list in a file \fI\&.rhosts\fP
in his login directory.  Each line in this file should contain a \fIrhost\fP
and a \fIusername\fP separated by a space, giving additional cases
where logins without passwords are to be permitted.
If the originating user is not equivalent to the remote user, then
a login and password will be prompted for on the remote machine as in
.IR login (1).
To avoid some security problems, the \fI\&.rhosts\fP file must be owned by
either the remote user or root and may not be a symbolic link.
.PP
Your remote terminal type is the same as your local
terminal type (as given in your environment TERM variable).
All echoing takes place at the remote site, so that (except for
delays) the rlogin is transparent.  Flow control via ^S and ^Q and
flushing of input and output on interrupts are handled properly.
A line of the form ``~.'' disconnects from the remote host, where
``~'' is the escape character.  A different escape character may
be specified by the
.B \-e
option.
There is no space separating this option flag and the argument
character.
.SH SEE ALSO
rsh(1C)
.SH FILES
/usr/hosts/*		for \fIrhost\fP version of the command
.br
/etc/hosts.equiv
.br
$HOME/.rhosts
.SH BUGS
More terminal characteristics should be propagated.
.PP
On System V systems, users are required to enter their password
(if they have one) on the remote system.
This is due to the operation of
.I login
on these systems.
.SH CAVEAT
.I Rlogin
is available on CMC TCP Releases 2.0 and later.
.I Telnet
is available on all releases for interactive access to remote systems.
ser for it (after disabling local echo).
If an account field is not specified, and the FTP server
requires it, the user will be prompted for it.  Unless
.I ftp
is invoked with \*(lqauto-login\*(rq disabled, this
process is done automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, allunix/man/man1/rsh.1c                                                                                   444     322     145         4620  3621344660   7545                                                                                                                                                                                                                                                                                                                                                                      .TH RSH 1C "" CMC
.UC 4
.SH NAME
rsh \- remote shell
.SH SYNOPSIS
.B rsh
host
[
.B \-l
username
] [
.B \-n
] command
.br
host
[
.B \-l
username
] [
.B \-n
] command
.SH DESCRIPTION
.I Rsh
connects to the specified
.I host,
and executes the specified \fIcommand\fR.
.I Rsh
copies its standard input to the remote command, the standard
output of the remote command to its standard output, and the
standard error of the remote command to its standard error.
Interrupt, quit and terminate signals are propagated to the remote
command; \fIrsh\fP normally terminates when the remote command does.
.PP
The remote username used is the same as your local username,
unless you specify a different remote name with the
.B \-l
option.
This remote name must be equivalent (in the sense of
.IR rlogin (1C))
to the originating account; no provision
is made for specifying a password with a command.
.PP
If you omit
.I command,
then instead of executing a single command, you will be logged in
on the remote host using
.IR rlogin (1C).
.PP
Shell metacharacters which are not quoted are interpreted
on local machine, while quoted metacharacters are interpreted on
the remote machine.
Thus the command
.PP
\ \ \ rsh otherhost cat remotefile >> localfile
.PP
appends the remote file
.I remotefile
to the localfile
.I localfile,
while
.PP
\ \ \ rsh otherhost cat remotefile ">>" otherremotefile
.PP
appends
.I remotefile
to
.I otherremotefile.
.PP
Host names are given in the file /etc/hosts.  Each host
has one standard name (the first name given in the file), which
is rather long and unambiguous, and optionally one or more nicknames.
The host names for local machines are also commands in the directory
/usr/hosts; if you put this directory in your search path
then the
.B rsh
can be omitted.
.SH FILES
.ta 2i
/etc/hosts
.br
/usr/hosts/*
.br
/etc/hosts.equiv (on remote host)
.br
$HOME/.rhosts (on remote host)
.DT
.SH SEE ALSO
rlogin(1C), hosts(5)
.SH NOTES
.I Rlogin
must be located in the standard search path in order to be
found by a command-less invocation of
.IR rsh .
.SH EXAMPLES
A typical file in the /usr/hosts directory is the file "cyb",
which has execute access and contents of:
.sp
	rsh cyb $*
.SH BUGS
You cannot run an interactive command
(like
.IR rogue (6)
or
.IR vi (1));
use
.IR rlogin (1C).
.PP
Stop signals stop the local \fIrsh\fP process only; this is arguably
wrong, but currently hard to fix for reasons too complicated to
explain here.
automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, allunix/man/man1/sink.1c                                                                                  444     322     145          642  3621344660   7675                                                                                                                                                                                                                                                                                                                                                                      .TH SINK 1C "" CMC
.SH NAME
sink - canonical "server" process for testing network
.SH SYNOPSIS
.B sink
.SH DESCRIPTION
.I Sink
spawns a daemon which listens on the port used by the
TCP sink service.
As connections are made to that port,
.I sink
reads and discards any incoming data for the duration of the connection.
Multiple and simultaneous connections are supported.
.SH FILES
/etc/services	determines port number
emote command to its standard error.
Interrupt, quit and terminate signals are propagated to tunix/man/man1/telnet.1c                                                                                444     322     145         5633  3621344661  10252                                                                                                                                                                                                                                                                                                                                                                      .TH TELNET 1C "" "CMC"
.UC 4
.SH NAME
telnet \- user interface to the TELNET protocol
.SH SYNOPSIS
telnet [ host [ port ] ]
.SH DESCRIPTION
.I Telnet
is used to communicate with another host using the TELNET protocol.  If 
.I telnet
is invoked without arguments, it enters command mode,
indicated by its prompt (\*(lqtelnet>\*(rq).
In this mode, it accepts and executes the commands listed below.
If it is invoked with arguments, it performs an
.I open
command (see below) with those arguments.
.PP
Once a connection has been opened,
.I telnet
enters input mode.
In this mode, text typed is sent to the remote host.  To issue
.I telnet
commands when in input mode, precede them with the
.I telnet
\*(lqescape character\*(rq (initially \*(lq^[\*(rq).
When in command mode, the normal terminal editing conventions are available.
.PP
The following commands are available.
Only enough of each command to uniquely identify it need be typed.
.PP
.TP
\fBopen\fP \fIhost\fP [ \fIport\fP ]
Open a connection to the named host.  If no port number
is specified, 
.I telnet
will attempt to contact a TELNET server at the default port.
The host specification may be either a host name (see 
.IR hosts (5))
or an Internet address specified in the \*(lqdot notation\*(rq.
.TP
\fBconnect\fP \fIhost\fP [ \fIport\fP ]
Synonym for
.IR open .
.TP
.B close
Close a TELNET session and return to command mode.
.TP
.B quit
Close any open TELNET session and exit 
.IR telnet .
.TP
.B bye
Synonym for
.IR quit .
.TP
.B z
Suspend
.IR telnet .
This command only works when the user is using the 
.IR csh (1).
.TP
\fBescape\fP [ \fIescape-char\fP ]
Set the 
.I telnet
\*(lqescape character\*(rq.  Control characters may
be specified as \*(lq^\*(rq followed by a single
letter; e.g. \*(lqcontrol-X\*(rq is \*(lq^X\*(rq.
.TP
.B status
Show the current status of 
.IR telnet .
This includes the peer one is connected to, as well
as the state of debugging.
.TP
.B options
Toggle viewing of TELNET options processing.  When
options viewing is enabled, all TELNET option negotiation (   (  s
will be displayed.  Options sent by 
.I telnet
are displayed as \*(lqSENT\*(rq, while options
received from the TELNET server are displayed as
\*(lqRCVD\*(rq.
.TP
.B crmod
Toggle carriage return mode.  When this mode is enabled
any carriage return characters received from the remote
host will be mapped into a carriage return and a line
feed.  This mode does not affect those characters typed
by the user, only those received.  This mode is not very
useful, but is required for some hosts that like to ask
the user to do local echoing.
.TP
\fB?\fP [ \fIcommand\fP ]
Get help.  With no arguments,
.I telnet
prints a help summary.
If a command is specified, 
.I telnet
will print the help information available about the command only.
.TP
\fBhelp\fP [ \fIcommand\fP ]
Synonym for
.IR ?.
.SH BUGS
This implementation is very simple because
.IR rlogin (1C)
is the standard mechanism used to communicate locally 
with hosts.
ed be typed.
.PP
.TP
\fBopen\fP \fIhost\fP [ \fIport\fP ]
Open a connection to the named host.  If nounix/man/man3/                                                                                         750     322     145            0  3621344700   6427                                                                                                                                                                                                                                                                                                                                                                      unix/man/man3/accept.3n                                                                                444     322     145         4220  3621344662  10225                                                                                                                                                                                                                                                                                                                                                                      .TH ACCEPT 3N "" CMC
.UC 4
.SH NAME
accept \- accept a connection on a socket
.SH SYNOPSIS
.ft B
.nf
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
ns = accept(s, addr, addrlen)
int ns, s;
struct sockaddr *addr;
int *addrlen;
.fi
.SH DESCRIPTION
The argument
.I s
is a socket which has been created with
.IR socket (3N),
bound to an address with
.IR bind (3N),
and is listening for connections after a
.IR listen (3N).
.I Accept
extracts the first connection
on the queue of pending connections, creates
a new socket with the same properties of 
.I s
and allocates a new file descriptor,
.IR ns ,
for the socket.  If no pending connections are
present on the queue, and the socket is not marked
as non-blocking,
.I accept
blocks the caller until a connection is present.
If the socket is marked non-blocking and no pending
connections are present on the queue, 
.I accept
returns an error as described below.
The accepted socket,
.IR ns ,
may not be used
to accept more connections.  The original socket
.I s
remains open.
.PP
The argument
.I addr
is a result parameter which is filled in with
the address of the connecting entity,
as known to the communications layer.
The exact format of the
.I addr
parameter is determined by the domain in which the communication
is occurring.
The 
.I addrlen
is a value-result parameter; it should initially contain the
amount of space pointed to by
.IR addr ;
on return it will contain the actual length (in bytes) of the
address returned.
This call
is used with connection-based socket types, currently with SOCK_STREAM.
.SH "RETURN VALUE
The call returns \-1 on error.  If it succeeds it returns a non-negative
integer which is a descriptor for the accepted socket.
.SH ERRORS
The \fIaccept\fP will fail if:
.TP 20
[EBADF]
The descriptor is invalid.
.TP 20
[ENOTSOCK]
The descriptor references a file, not a socket.
.TP 20
[EOPNOTSUPP]
The referenced socket is not of type SOCK_STREAM.
.TP 20
[EFAULT]
The \fIaddr\fP parameter is not in a writable part of the
user address space.
.TP 20
[EWOULDBLOCK]
The socket is marked non-blocking and no connections
are present to be accepted.
.SH SEE ALSO
bind(3N), connect(3N), listen(3N), socket(3N)

.SH BUGS
You cannot run an interactive command
(like
.IR rogue (6)
or
.IR vi (1));
use
.IR rlogin (1C).
.PP
Stop signals stop the local \fIrsh\fP process only; this is arguably
wrong, but currently hard to fix for reasons too complicated to
explain here.
automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, allunix/man/man3/bind.3n                                                                                  444     322     145         2536  3621344663   7713                                                                                                                                                                                                                                                                                                                                                                      .TH BIND 3N "" CMC
.UC 4
.SH NAME
bind \- bind a name to a socket
.SH SYNOPSIS
.nf
.ft B
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
bind(s, name, namelen)
int s;
struct sockaddr *name;
int namelen;
.fi
.SH DESCRIPTION
.I Bind
assigns a name to an unnamed socket.
When a socket is created 
with
.IR socket (3n)
it exists in a name space (address family)
but has no name assigned.
.I Bind
requests the
.IR name ,
be assigned to the socket.
.SH NOTES
The rules used in name binding vary between communication domains.
Consult the manual entries in section 4 for detailed information.
.SH "RETURN VALUE
If the bind is successful, a 0 value is returned.
A return value of \-1 indicates an error, which is
further specified in the global \fIerrno\fP.
.SH ERRORS
The \fIbind\fP call will fail if:
.TP 20
[EBADF]
\fIS\fP is not a valid descriptor.
.TP 20
[ENOTSOCK]
\fIS\fP is not a socket.
.TP 20
[EADDRNOTAVAIL]
The specified address is not available from the local machine.
.TP 20
[EADDRINUSE]
The specified address is already in use.
.TP 20
[EINVAL]
The socket is already bound to an address.
.TP 20
[EACCESS]
The requested address is protected, and the current user
has inadequate permission to access it.
.TP 20
[EFAULT]
The \fIname\fP parameter is not in a valid part of the user
address space.
.SH SEE ALSO
connect(3n), listen(3n), socket(3n), getsockname(3n)
 of space pointed to by
.IR addr ;
on return it will contain the actual length (in bytes) of the
address returned.
This call
is used with connection-based socket unix/man/man3/byteorder.3n                                                                             444     322     145         1750  3621344663  10773                                                                                                                                                                                                                                                                                                                                                                      .TH BYTEORDER 3N "" CMC
.UC 4
.SH NAME
htonl, htons, ntohl, ntohs \- convert values between host and network byte order
.SH SYNOPSIS
.nf
.B #include <CMC/types.h>
.B #include <CMC/in.h>
.PP
.B netlong = htonl(hostlong);
.B u_long netlong, hostlong;
.PP
.B netshort = htons(hostshort);
.B u_short netshort, hostshort;
.PP
.B hostlong = ntohl(netlong);
.B u_long hostlong, netlong;
.PP
.B hostshort = ntohs(netshort);
.B u_short hostshort, netshort;
.fi
.SH DESCRIPTION
These routines convert 16 and 32 bit quantities between network
byte order and host byte order.  On machines such as the SUN
these routines are defined as null macros in the include file
.RI < CMC/in.h >.
.PP
These routines are most often used in conjunction with Internet
addresses and ports as returned by
.IR gethostent (3N)
and
.IR getservent (3N).
.SH "SEE ALSO"
gethostent(3N),
getservent(3N)
.SH BUGS
The VAX handles bytes backwards from most everyone else in
the world.  This is not expected to be fixed in the near future.
E]
The specified addressunix/man/man3/connect.3n                                                                               444     322     145         3300  3621344664  10417                                                                                                                                                                                                                                                                                                                                                                      .TH CONNECT 3N "" CMC
.UC 4
.SH NAME
connect \- initiate a connection on a socket
.SH SYNOPSIS
.nf
.ft B
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
connect(s, name, namelen)
int s;
struct sockaddr *name;
int namelen;
.fi
.SH DESCRIPTION
The parameter
.I s
is a socket.
If it is of type SOCK_DGRAM,
then this call permanently specifies the peer to which
datagrams are to be sent;
if it is of type SOCK_STREAM,
then this call attempts to make a connection to
another socket.
The other socket is specified by
.I name
which is an address in the communications space of the socket.
Each communications space interprets the
.I name
parameter in its own way.
.SH "RETURN VALUE
If the connection or binding succeeds, then 0 is returned.
Otherwise a \-1 is returned, and a more specific error
code is stored in \fIerrno\fP.
.SH "ERRORS
The call fails if:
.TP 20
[EBADF]
.I S
is not a valid descriptor.
.TP 20
[ENOTSOCK]
.I S
is a descriptor for a file, not a socket.
.TP 20
[EADDRNOTAVAIL]
The specified address is not available on this machine.
.TP 20
[EAFNOSUPPORT]
Addresses in the specified address family cannot be used with this socket.
.TP 20
[EISCONN]
The socket is already connected.
.TP 20
[ETIMEDOUT]
Connection establishment timed out without establishing a connection.
.TP 20
[ECONNREFUSED]
The attempt to connect was forcefully rejected.
.TP 20
[ENETUNREACH]
The network isn't reachable from this host.
.TP 20
[EADDRINUSE]
The address is already in use.
.TP 20
[EFAULT]
The \fIname\fP parameter specifies an area outs (   (  ide
the process address space.
.TP 20
[EWOULDBLOCK]
The socket is non-blocking and the
and the connection cannot
be completed immediately.
.SH SEE ALSO
accept(3N), socket(3N), getsockname(3N)
s;
struct sockaddr *name;
int namelen;
.fi
.SH DESCRIPTION
The parameter
.I s
is a socket.
If it is of type SOCK_DGRAM,
then this call permanently specifies the peer to which
datagrams are to be sent;
if it is of type SOCK_STREAM,
then this call attempts to make a connection to
another socket.
The other socket is speciunix/man/man3/directory.3                                                                              444     322     145         3763  3621344664  10631                                                                                                                                                                                                                                                                                                                                                                      .TH DIRECTORY 3 "" CMC
.UC 4
.SH NAME
opendir, readdir, telldir, seekdir, rewinddir, closedir \- directory operations
.SH SYNOPSIS
.B #include <CMC/dir.h>
.PP
.SM
.B dirid = 
.B opendir(filename)
.SM
.br
.B int dirid;
.br
.B char *filename;
.PP
.B struct direct
.B *readdir(dirid)
.SM
.br
.B int
.B dirid;
.PP
.B loc =
.B telldir(dirid)
.SM
.br
.B long loc;
.br
.B int
.B dirid;
.PP
.B seekdir(dirid, loc)
.br
.SM
.B int
.B dirid;
.br
.B long loc;
.PP
.B rewinddir(dirid)
.br
.SM
.B int
.B dirid;
.PP
.B closedir(dirid)
.br
.SM
.B int
.B dirid;
.SH DESCRIPTION
.I Opendir
opens the directory named by
.IR filename .
.I Opendir
returns an integer to be used to identify the
directory 
in subsequent operations.  A -1
is returned if
.I filename
cannot be accessed.
.PP
.I Readdir
returns a pointer to the next directory entry.  It returns
.B NULL
upon reaching the end of the directory or detecting an invalid
.I seekdir
operation.
.PP
.I Telldir
returns the current location associated with the named
directory.
.PP
.I Seekdir
sets the position of the next
.I readdir
operation on the
directory.
The new position reverts to the one associated with the
directory
when the
.I telldir
operation was performed.
.PP
.I Rewinddir
resets the position 
to the beginning of the directory.
.PP
.I Closedir
closes the named
directory.
.PP
The directory structure returned by
.I readdir
is defined in
.RI < CMC/dir.h >
as:
.PP
#define	MAXNAMLEN	14
.br
struct	direct {
.br
	u_long d_ino;  /* inode number of entry;
.br
	                  0 for unused directory slots */
.br
	char   d_name[MAXNAMLEN + 1];
.br
	               /* name will be null terminated */
.br
};
.PP
Sample code which searchs a directory for entry ``name'' is:
.PP
.br
	dirid = opendir(".");
.br
	for (dp = readdir(dirid); dp != NULL;
.br
	     dp = readdir(dirid)) {
.br
		if (dp->d_ino && !strcmp(dp->d_name, name)) {
.br
			closedir(dirid);
.br
			return FOUND;
.br
		}
.br
	}
.br
	closedir(dirid);
.br
	return NOT_FOUND;
.SH "SEE ALSO"
open(2),
close(2),
read(2),
lseek(2).
20
[EWOULDBLOunix/man/man3/gethostent.3n                                                                            444     322     145         4246  3621344665  11165                                                                                                                                                                                                                                                                                                                                                                      .TH GETHOSTENT 3N "" CMC
.UC 4
.SH NAME
gethostent, gethostbyaddr, gethostbyname, sethostent, endhostent \- get network host entry
.SH SYNOPSIS
.B "#include <CMC/netdb.h>
.PP
.B "struct hostent *gethostent()
.PP
.B "struct hostent *gethostbyname(name)
.br
.B "char *name;
.PP
.B "struct hostent *gethostbyaddr(addr, len, type)
.br
.B "char *addr; int len, type;
.PP
.B "sethostent(stayopen)
.br
.B "int stayopen;
.PP
.B "endhostent()
.SH DESCRIPTION
.IR Gethostent ,
.IR gethostbyname ,
and
.I gethostbyaddr
each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the network host data base,
.IR /etc/hosts .
.RS
.PP
.nf
struct	hostent {
	char	*h_name;	/* official name of host */
	char	**h_aliases;	/* alias list */
	int	h_addrtype;	/* address type */
	int	h_length;	/* length of address */
	char	*h_addr;	/* address */
};
.ft R
.ad
.fi
.RE
.PP
The members of this structure are:
.TP \w'h_addrtype'u+2n
h_name
Official name of the host.
.TP \w'h_addrtype'u+2n
h_aliases
A zero terminated array of alternate names for the host.
.TP \w'h_addrtype'u+2n
h_addrtype
The type of address being returned; currently always AF_INET.
.TP \w'h_addrtype'u+2n
h_length
The length, in bytes, of the address.
.TP \w'h_addrtype'u+2n
h_addr
A pointer to the network address for the host.
Host addresses are returned
in network byte order.
.PP
.I Gethostent
reads the next line of the file, opening the file if necessary.
.PP
.I Sethostent
opens and rewinds the file.  If the
.I stayopen
flag is non-zero,
the host data base will not be closed after each call to 
.I gethostent
(either directly, or indirectly through one of the other
\*(lqgethost\*(rq calls).
.PP
.I Endhostent
closes the file.
.PP
.I Gethostbyname
and
.I gethostbyaddr
sequentially search from the beginning
of the file until a matching
host name or
host address is found,
or until EOF is encountered.
Host addresses are supplied in network order.
.SH FILES
/etc/hosts
.SH "SEE ALSO"
hosts(5)
.SH DIAGNOSTICS
Null pointer
(0) returned on EOF or error.
.SH BUGS
All information
is contained in a static area
so it must be copied if it is
to be saved.  Only the Internet
address format is currently understood.
un an interactive command
(like
.IR rogue (6)
or
.IR vi (1));
use
.IR rlogin (1C).
.PP
Stop signals stop the local \fIrsh\fP process only; this is arguably
wrong, but currently hard to fix for reasons too complicated to
explain here.
automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, allunix/man/man3/gethostname.3n                                                                           444     322     145         2164  3621344666  11315                                                                                                                                                                                                                                                                                                                                                                      .TH GETHOSTNAME 3N "" CMC
.UC 4
.SH NAME
gethostname - get name of current host
.SH SYNOPSIS
.nf
.ft B
gethostname(name, namelen)
char *name;
int namelen;
.PP
.fi
.SH DESCRIPTION
.I Gethostname
returns the standard network node name for the current Unix system.
The parameter
.I namelen
specifies the size of the 
.I name
array.  The returned name is null-terminated unless insufficient
space is provided.
.PP
.I Gethostname
attempts to get the system's node name via the system call
.IR uname (3N).
If this fails, it reads the name from the file 
.I /etc/host.
.SH "RETURN VALUE
If the call succeeds a value of 0 is returned.  If the call
fails, then a value of \-1 is returned and an error code is
placed in the global location \fIerrno\fP.
.SH "ERRORS
The following errors may be returned by this call:
.TP 15
[EFAULT]
The \fIname\fP or \fInamelen\fP parameter gave an
invalid address.
.TP 15
[EPERM]
The caller was not the super-user.
.TP 15
[ENOENT]
The file \fI/etc/host\fP didn't exist.
.TP 15
[EACCESS]
The caller did not have access to \fI/etc/host\fP.
.SH FILES
/etc/host
.SH BUGS
.I Uname
limits host node names to 8 characters.
g returned; currently always AF_INET.
.TP \w'h_addrtype'u+2n
h_length
The length, in bytes, of the address.
.TP \w'h_addrtype'u+2n
h_addr
A pointer to the network address for the host.
Host addresses are returned
in network byte order.
.PP
.I Gethostent
reads the next line of the file, opening the file if necessary.
.PP
.I Sethostent
opens and rewinds the file.  If the
.I stayopen
flag is non-unix/man/man3/getnetent.3n                                                                             444     322     145         4104  3621344667  10771                                                                                                                                                                                                                                                                                                                                                                      .TH GETNETENT 3N "" CMC
.UC 4
.SH NAME
getnetent, getnetbyaddr, getnetbyname, setnetent, endnetent \- get network entry
.SH SYNOPSIS
.nf
.ft B
#include <CMC/netdb.h>
.PP
.ft B
struct netent *getnetent()
.PP
.ft B
struct netent *getnetbyname(name)
char *name;
.PP
.ft B
struct netent *getnetbyaddr(net, type)
int net, type;
.PP
.ft B
setnetent(stayopen)
int stayopen;
.PP
.ft B
endnetent()
.fi
.SH DESCRIPTION
.IR Getnetent ,
.IR getnetbyname ,
and
.I getnetbyaddr
each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the network data base,
.IR /etc/networks .
.RS
.PP
.nf
struct	netent {
	char	*n_name;	/* official name of net */
	char	**n_aliases;	/* alias list */
	int	n_addrtype;	/* net number type */
	long	n_net;		/* net number */
};
.ft R
.ad
.fi
.RE
.PP
The members of this structure are:
.TP \w'n_addrtype'u+2n
n_name
The official name of the network.
.TP \w'n_addrtype'u+2n
n_aliases
A zero terminated list of alternate names for the network.
.TP \w'n_addrtype'u+2n
n_addrtype
The type of the network number returned; currently only AF_INET.
.TP \w'n_addrtype'u+2n
n_net
The network number.  Network numbers are returned in machine byte
order.
.PP
.I Getnetent
reads the next line of the file, opening the file if necessary.
.PP
.I Setnetent
opens and rewinds the file.  If the
.I stayopen
flag is non-zero,
the net data base will not be closed after each call to 
.I getnetent
(either directly, or indirectly through one of
the other \*(lqgetnet\*(rq calls).
.PP
.I End (   (  netent
closes the file.
.PP
.I Getnetbyname
and
.I getnetbyaddr
sequentially search from the beginning
of the file until a matching
net name or
net address is found,
or until EOF is encountered.
Network numbers are supplied in host order.
.SH FILES
/etc/networks
.SH "SEE ALSO"
networks(5)
.SH DIAGNOSTICS
Null pointer
(0) returned on EOF or error.
.SH BUGS
All information
is contained in a static area
so it must be copied if it is
to be saved.  Only Internet network
numbers are currently understood.
Expecting network numbers to fit
in no more than 32 bits is probably
naive.
twork data base,
.IR /etc/networks .
.RS
.PP
.nf
struct	netent {
	char	*n_name;	/* official name of net */
	char	**n_aliases;	/* alias list */
	int	n_addrtype;	/* net number type */
	long	n_net;		/* net number */
};
.ft R
.ad
.fi
.RE
.PP
The members of this structure are:
.TP \w'n_addrtype'u+2n
n_name
The official name of the network.
.TP \w'n_addrtype'u+2n
n_aliases
A zero terminated list of alternate names for the network.
.TP \w'n_addrtyunix/man/man3/getpeername.3n                                                                           444     322     145         1733  3621344670  11267                                                                                                                                                                                                                                                                                                                                                                      .TH GETPEERNAME 3N "" CMC
.UC 4
.SH NAME
getpeername \- get name of connected peer
.SH SYNOPSIS
.nf
.PP
.ft B
getpeername(s, name, namelen)
int s;
struct sockaddr *name;
int *namelen;
.fi
.SH DESCRIPTION
.I Getpeername
returns the name of the peer connected to
socket
.IR s .
The
.I namelen
parameter should be initialized to indicate
the amount of space pointed to by
.IR name .
On return it contains the actual size of the name
returned (in bytes).
.SH DIAGNOSTICS
A 0 is returned if the call succeeds, \-1 if it fails.
.SH ERRORS
The call succeeds unless:
.TP 15
[EBADF]
The argument \fIs\fP is not a valid descriptor.
.TP 15
[ENOTSOCK]
The argument \fIs\fP is a file, not a socket.
.TP 15
[ENOTCONN]
The socket is not connected.
.TP 15
[ENOBUFS]
Insufficient resources were available in the system
to perform the operation.
.TP 15
[EFAULT]
The 
.I name
parameter points to memory not in a valid part of the
process address space.
.SH "SEE ALSO"
bind(3N), socket(3N), getsockname(3N)
ames for the network.
.TP \w'n_addrtyunix/man/man3/getprotoent.3n                                                                           444     322     145         3543  3621344670  11346                                                                                                                                                                                                                                                                                                                                                                      .TH GETPROTOENT 3N "" CMC
.UC 4
.SH NAME
getprotoent, getprotobynumber, getprotobyname, setprotoent, endprotoent \- get protocol entry
.SH SYNOPSIS
.nf
.ft B
.B #include <CMC/netdb.h>
.PP
.ft B
struct protoent *getprotoent()
.PP
.ft B
struct protoent *getprotobyname(name)
char *name;
.PP
.ft B
struct protoent *getprotobynumber(proto)
int proto;
.PP
.ft B
setprotoent(stayopen)
int stayopen;
.PP
.ft B
endprotoent()
.fi
.SH DESCRIPTION
.IR Getprotoent ,
.IR getprotobyname ,
and
.I getprotobynumber
each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the network protocol data base,
.IR /etc/protocols .
.RS
.PP
.nf
struct	protoent {
	char	*p_name;	/* official name of protocol */
	char	**p_aliases;	/* alias list */
	long	p_proto;	/* protocol number */
};
.ft R
.ad
.fi
.RE
.PP
The members of this structure are:
.TP \w'p_aliases'u+2n
p_name
The official name of the protocol.
.TP \w'p_aliases'u+2n
p_aliases
A zero terminated list of alternate names for the protocol.
.TP \w'p_aliases'u+2n
p_proto
The protocol number.
.PP
.I Getprotoent
reads the next line of the file, opening the file if necessary.
.PP
.I Setprotoent
opens and rewinds the file.  If the
.I stayopen
flag is non-zero,
the net data base will not be closed after each call to 
.I getprotoent
(either directly, or indirectly through one of
the other \*(lqgetproto\*(rq calls).
.PP
.I Endprotoent
closes the file.
.PP
.I Getprotobyname
and
.I getprotobynumber
sequentially search from the beginning
of the file until a matching
protocol name or
protocol number is found,
or until EOF is encountered.
.SH FILES
/etc/protocols
.SH "SEE ALSO"
protocols(5)
.SH DIAGNOSTICS
Null pointer
(0) returned on EOF or error.
.SH BUGS
All information
is contained in a static area
so it must be copied if it is
to be saved.  Only the Internet
protocols are currently understood.
is encountered.
Host addresses are supplied in network order.
.SH FILES
/etc/hosts
.SH "SEE ALSO"
hosts(5)
.SH DIAGNOSTICS
Null pointer
(0) returned on EOF ounix/man/man3/getservent.3n                                                                            444     322     145         4237  3621344672  11165                                                                                                                                                                                                                                                                                                                                                                      .TH GETSERVENT 3N "" CMC
.UC 4
.SH NAME
getservent, getservbyport, getservbyname, setservent, endservent \- get service entry
.SH SYNOPSIS
.nf
.ft B
#include <CMC/netdb.h>
.PP
.ft B
struct servent *getservent()
.PP
.ft B
struct servent *getservbyname(name, proto)
char *name, *proto;
.PP
.ft B
struct servent *getservbyport(port, proto)
int port; char *proto;
.PP
.ft B
setservent(stayopen)
int stayopen;
.PP
.ft B
endservent()
.fi
.SH DESCRIPTION
.IR Getservent ,
.IR getservbyname ,
and
.I getservbyport
each return a pointer to an object with the
following structure
containing the broken-out
fields of a line in the network services data base,
.IR /etc/services .
.RS
.PP
.nf
struct	servent {
	char	*s_name;	/* official name of service */
	char	**s_aliases;	/* alias list */
	long	s_port;		/* port service resides at */
	char	*s_proto;	/* protocol to use */
};
.ft R
.ad
.fi
.RE
.PP
The members of this structure are:
.TP \w's_aliases'u+2n
s_name
The official name of the service.
.TP \w's_aliases'u+2n
s_aliases
A zero terminated list of alternate names for the service.
.TP \w's_aliases'u+2n
s_port
The port number at which the service resides.
Port numbers are returned in network byte order.
.TP \w's_aliases'u+2n
s_proto
The name of the protocol to use when contacting the
service.
.PP
.I Getservent
reads the next line of the file, opening the file if necessary.
.PP
.I Setservent
opens and rewinds the file.  If the
.I stayopen
flag is non-zero,
the net data base will not be closed after each call to 
.I getservent
(either directly, or indirectly through one of
the other \*(lqgetserv\*(rq calls).
.PP
.I Endservent
closes the file.
.PP
.I Getservbyname
and
.I getservbyport
sequentially search from the beginning
of the file until a matching
protocol name or
port number is found,
or until EOF is encountered.
If a protocol name is also supplied (non-NULL),
searches must also match the protocol.
.SH FILES
/etc/services
.SH "SEE ALSO"
getprotoent(3N), services(5)
.SH DIAGNOSTICS
Null pointer
(0) returned on EOF or error.
.SH BUGS
All information
is contained in a static area
so it must be copied if it is
to be saved.  Expecting port
numbers to fit in a 32 bit
quantity is probably naive.
stood.
un an interactive command
(like
.IR rogue (6)
or
.IR vi (1));
use
.IR rlogin (1C).
.PP
Stop signals stop the local \fIrsh\fP process only; this is arguably
wrong, but currently hard to fix for reasons too complicated to
explain here.
automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, allunix/man/man3/getsockname.3n                                                                           444     322     145         1617  3621344672  11276                                                                                                                                                                                                                                                                                                                                                                      .TH GETSOCKNAME 3N "" CMC
.UC 4
.SH NAME
getsockname \- get socket name
.SH SYNOPSIS
.nf
.PP
.ft B
getsockname(s, name, namelen)
int s;
struct sockaddr *name;
int *namelen;
.fi
.SH DESCRIPTION
.I Getsockname
returns the current 
.I name
for the specified socket.  The
.I namelen
parameter should be initialized to indicate
the amount of space pointed to by
.IR name .
On return it contains the actual size of the name
returned (in bytes).
.SH DIAGNOSTICS
A 0 is returned if the call succeeds, \-1 if it fails.
.SH ERRORS
The call succeeds unless:
.TP 15
[EBADF]
The argument \fIs\fP is not a valid descriptor.
.TP 15
[ENOTSOCK]
The argument \fIs\fP is a file, not a socket.
.TP 15
[ENOBUFS]
Insufficient resources were available in the system
to perform the operation.
.TP 15
[EFAULT]
The 
.I name
parameter points to memory not in a valid part of the
process address space.
.SH "SEE ALSO"
bind(3N), socket(3N)
cture are:
.TP \w's_aliases'u+2n
s_name
The official name of the service.
.TP \w's_aliases'u+2n
s_aliases
A zero unix/man/man3/getsockopt.3n                                                                            444     322     145         4375  3621344673  11165                                                                                                                                                                                                                                                                                                                                                                       (   (  .TH GETSOCKOPT 3N "" CMC
.UC 4
.SH NAME
getsockopt, setsockopt \- get and set options on sockets
.SH SYNOPSIS
.nf
.ft B
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
getsockopt(s, level, optname, optval, optlen)
int s, level, optname;
char *optval;
int *optlen;
.sp
setsockopt(s, level, optname, optval, optlen)
int s, level, optname;
char *optval;
int optlen;
.fi
.SH DESCRIPTION
.I Getsockopt
and
.I setsockopt
manipulate
.I options
associated with a socket.  Options may exist at multiple
protocol levels; they are always present at the uppermost
``socket'' level.
.PP
When manipulating socket options the level at which the
option resides and the name of the option must be specified.
To manipulate options at the ``socket'' level,
.I level
is specified as SOL_SOCKET.  To manipulate options at any
other level the protocol number of the appropriate protocol
controlling the option is supplied.  For example,
to indicate an option is to be interpreted by the TCP protocol,
.I level
should be set to the protocol number of TCP; see
.IR getprotoent (3N).
.PP
The parameters
.I optval
and
.I optlen
are used to access option values for
.IR setsockopt .
For
.I getsockopt
they identify a buffer in which the value for the
requested option(s) are to be returned.  For
.IR getsockopt ,
.I optlen
is a value-result parameter, initially containing the
size of the buffer pointed to by
.IR optval ,
and modified on return to indicate the actual size of
the value returned.  If no option value is
to be supplied or returned,
.I optval
may be supplied as 0.
.PP
.I Optname
and any specified options are passed uninterpreted to the appropriate
protocol module for interpretation.
The include file
.RI < CMC/socket.h >
contains definitions for ``socket'' level options; see
.IR socket (3N).
Options at other protocol levels vary in format and
name, consult the appropriate entries in (4P).  
.SH "RETURN VALUE"
A 0 is returned if the call succeeds, \-1 if it fails.
.SH ERRORS
The call succeeds unless:
.TP 20
[EBADF]
The argument \fIs\fP is not a valid descriptor.
.TP 20
[ENOTSOCK]
The argument \fIs\fP is a file, not a socket.
.TP 20
[ENOPROTOOPT]
The option is unknown.
.TP 20
[EFAULT]
The options are not in a valid part of the
process address space.
.SH "SEE ALSO"
socket(3N), getprotoent(3N)
Stop signals stop the local \fIrsh\fP process only; this is arguably
wrong, but currently hard to fix for reasons too complicated to
explain here.
automatically on initial connection to
the FTP server.
.TP
.B verbose
Toggle verbose mode.  In verbose mode, allunix/man/man3/inet.3n                                                                                  444     322     145         6373  3621344673   7742                                                                                                                                                                                                                                                                                                                                                                      .TH INET 3N "" CMC
.UC 4
.SH NAME
inet_addr, inet_network, inet_ntoa, inet_makeaddr, inet_lnaof, inet_netof \- Internet address manipulation routines
.SH SYNOPSIS
.nf
.B "#include <CMC/types.h>
.B "#include <CMC/socket.h>
.B "#include <CMC/in.h>
.B "#include <CMC/inet.h>
.PP
.B "u_long inet_addr(cp)
.B "char *cp;
.PP
.B "u_long inet_network(cp)
.B "char *cp;
.PP
.B "char *inet_ntoa(in)
.B "struct inet_addr in;
.PP
.B "struct in_addr inet_makeaddr(net, lna)
.B "int net, lna;
.PP
.B "int inet_lnaof(in)
.B "struct in_addr in;
.PP
.B "int inet_netof(in)
.B "struct in_addr in;
.fi
.SH DESCRIPTION
The routines
.I inet_addr
and
.I inet_network
each interpret character strings representing
numbers expressed in the Internet standard \*(lq.\*(rq notation, 
returning numbers suitable for use
as Internet addresses and Internet network
numbers, respectively.  The routine
.I inet_ntoa
takes an Internet address and returns an ASCII
string representing the address in \*(lq.\*(rq notation.  The routine
.I inet_makeaddr
takes an Internet network number and a local
network address and constructs an Internet address
from it.  The routines
.I inet_netof
and
.I inet_lnaof
break apart Internet host addresses, returning
the network number and local network address part,
respectively.
.PP
All Internet address are returned in network
order (bytes ordered from left to right).
All network numbers and local address parts are
returned as machine format integer values.
.SH "INTERNET ADDRESSES"
Values specified using the \*(lq.\*(rq notation take one
of the following forms:
.RS
.nf
a.b.c.d
a.b.c
a.b
a
.RE
.fi
When four parts are specified, each is interpreted
as a byte of data and assigned, from left to right,
to the four bytes of an Internet address.  Note
that when an Internet address is viewed as a 32-bit
integer quantity on the VAX the bytes referred to
above appear as \*(lqd.c.b.a\*(rq.  That is, VAX bytes are
ordered from right to left.
.PP
When a three part address is specified, the last
part is interpreted as a 16-bit quantity and placed
in the right most two bytes of the network address.
This makes the three part address format convenient
for specifying Class B network addresses as
\*(lq128.net.host\*(rq.
.PP
When a two part address is supplied, the last part
is interpreted as a 24-bit quantity and placed in
the right most three bytes of the network address.
This makes the two part address format convenient
for specifying Class A network addresses as
\*(lqnet.host\*(rq.
.PP
When only one part is given, the value is stored
directly in the network address without any byte
rearrangement.
.PP
All numbers supplied as \*(lqparts\*(rq in a \*(lq.\*(rq notation
may be decimal, octal, or hexadecimal, as specified
in the C language (i.e. a leading 0x or 0X implies
hexadecimal; otherwise, a leading 0 implies octal;
otherwise, the number is interpreted as decimal).
.SH "SEE ALSO"
gethostent(3N), getnetent(3N), hosts(5), networks(5),
.SH DIAGNOSTICS
The value \-1 is returned by
.I inet_addr
and
.I inet_network
for malformed requests.
.SH BUGS
The problem of host byte ordering versus network byte ordering is
confusing.  A simple way to specify Class C network addresses in a manner
similar to that for Class B and Class A is needed.
The string returned by
.I inet_ntoa
resides in a static memory area.
 popen (3)
with the argument supplied, and reads (writes) from the stdout
(stdin).  If the shell command includes spaces, the argument
must be quoted; e.g. \*(lq"| ls -lt"\*(rq.  A particularly
useful example of this mechanism is: \*(lqdir |more\*(rq.
.TP
3)
Faunix/man/man3/listen.3n                                                                                444     322     145         2046  3621344674  10273                                                                                                                                                                                                                                                                                                                                                                      .TH LISTEN 3N "" CMC
.UC 4
.SH NAME
listen \- listen for connections on a socket
.SH SYNOPSIS
.nf
.ft B
listen(s, backlog)
int s, backlog;
.fi
.SH DESCRIPTION
To accept connections, a socket
is first created with
.IR socket (3N),
a backlog for incoming connections is specified with
.IR listen (3N)
and then the connections are
accepted with
.IR accept (3N).
The
.I listen
call applies only to sockets of type
SOCK_STREAM.
.PP
The
.I backlog
parameter defines the maximum length the queue of
pending connections may grow to.
If a connection
request arrives with the queue full the client will
receive an error with an indication of ECONNREFUSED.
.SH "RETURN VALUE
A 0 return value indicates success; \-1 indicates an error.
.SH "ERRORS
The call fails if:
.TP 20
[EBADF]
The argument \fIs\fP is not a valid descriptor.
.TP 20
[ENOTSOCK]
The argument \fIs\fP is not a socket.
.TP 20
[EOPNOTSUPP]
The socket is not of a type that supports the operation \fIlisten\fP.
.SH "SEE ALSO"
accept(3N), connect(3N), socket(3N)
.SH BUGS
The
.I backlog
is ignored (silently).

network address and constructs an Internet address
from it.  The routines
.I inet_netof
and
.I inet_lnaof
break apart Internet host addresses, returning
the network number and local network address part,
respectively.
.PP
All Internet address are returned in network
order (bytes ordered from left to right).
All network numbers and local address parts are
returned as machine format integer values.
.SH "INTERNET ADDRESSES"
Values specified using the \*(lq.\*(rq notation unix/man/man3/net_error.3n                                                                             444     322     145         1344  3621344674  10774                                                                                                                                                                                                                                                                                                                                                                      .TH NET_ERROR 3N "" CMC
.SH NAME
net_error \- get a pointer to the message corresponding to a network error code
.SH SYNOPSIS
.B char *net_error (num)
.br
.B int num;
.SH DESCRIPTION
.I Net_error
returns a pointer to the message string corresponding to error number
.I num
in the system error message tables,
.I sys_errlist
or
.I nsys_errlist.
This is the message, without the newline, that would be printed by
.I perror
if it were called with
.I errno
having the value of
.IR num .
.I Net_error
allows access to system error messages without indexing directly
into the message tables.
This is needed since the networking error messages are not necessarily
contiguous with the rest of the system messages.
.SH SEE ALSO
intro(2), perror(3n)
call fails if:
.TP 20
[EBADF]
The argument \fIs\fP is not a valid descriptor.
.TP 20
[ENOTSOCK]
The argument \fIs\fP is not a socket.
.TP 20
[EOPNOTSUPP]
The socket is not of a type that supports the operation \fIlisten\fP.
.SH "SEE ALSO"
accept(3N), connect(3N), socket(3N)
.SH BUGS
 (   (  unix/man/man3/perror.3                                                                                 444     322     145         3217  3621344675  10132                                                                                                                                                                                                                                                                                                                                                                      .TH PERROR 3 "" CMC
.SH NAME
perror, errno, sys_errlist, sys_nerr,
nsys_errlist, nsys_nerr \- system error messages
.SH SYNOPSIS
.B void perror (s)
.br
.B char \(**s;
.PP
.B extern int errno;
.PP
.B extern char \(**sys_errlist[ ];
.PP
.B extern int sys_nerr;
.PP
.B extern char \(**nsys_errlist[ ];
.PP
.B extern int nsys_nerr;
.SH DESCRIPTION
.I Perror\^
produces a message on the standard error output,
describing the last error encountered
during a call to a system or library function.
The argument string
.I s\^
is printed first, then a colon and a blank, then the message and a new-line.
To be of most use, the argument string should include the name
of the program that incurred the error.
The error number is taken from the external variable
.IR errno ,
which is set when errors occur but not cleared when
non-erroneous calls are made.
.PP
To simplify variant formatting
of messages, the arrays of message strings
.I sys_errlist\^
and
.I nsys_errlist\^
are provided.
.I Sys_errlist\^
contains messages native to this Unix system;
.I nsys_errlist\^
contains messages for networking errors.
.IR Net_error (3n)
can be used to get a pointer to the message, without the 
newline, corresponding the the current value of
.IR errno .
.PP
.I Sys_nerr\^
is the largest message number provided for in
.IR sys_errlist .
.I Nsys_nerr\^
is the number of messages in
.I nsys_errlist\^
(not the largest network message error number).
The use of
.I net_error\^
to access error messges is preferrable to indexing into the
.I sys_errlist
and
.I nsys_errlist\^
tables since these tables are not guaranteed to have entries for
all possible error numbers.
.SH SEE ALSO
intro(2), net_error(3n)
ssigned, from left to right,
to the four bytes of an Internet address.  Note
that when an Internet address is viewed as a 32-bit
integer quantity on the VAX the bytes referred to
above appear as \*(lqd.c.b.a\*(rq.  That is, VAX bytes are
ordered from right to left.
.PP
When a three part address is specified, the last
part is interpreted as a 16-bit quantity and placeunix/man/man3/rcmd.3x                                                                                  444     322     145         5712  3621344675   7740                                                                                                                                                                                                                                                                                                                                                                      .TH RCMD 3X "" CMC
.UC 4
.SH NAME
rcmd, rresvport, ruserok \- routines for returning a stream to a remote command
.SH SYNOPSIS
.nf
.B "rem = rcmd(ahost, inport, locuser, remuser, cmd, fd2p);"
.B char **ahost;
.B u_short inport;
.B "char *locuser, *remuser, *cmd;"
.B int *fd2p;
.PP
.B s = rresvport(port);
.B int *port;
.PP
.B "ruserok(rhost, superuser, ruser, luser);"
.B char *rhost;
.B int superuser;
.B char *ruser, *luser;
.fi
.SH DESCRIPTION
.I Rcmd
is a routine used by the super-user to execute a command on
a remote machine using an authentication scheme based
on reserved port numbers.
.I Rresvport
is a routine which returns a descriptor to a socket
with an address in the privileged port space.
.I Ruserok
is a routine used by servers
to authenticate clients requesting service with
.IR rcmd .
All three functions are present in the same file and are used
by the
.IR rshd (8C)
server (among others).
.PP
.I Rcmd
looks up the host
.I *ahost
using
.IR gethostbyname (3N),
returning \-1 if the host does not exist.
Otherwise
.I *ahost
is set to the standard name of the host
and a connection is established to a server
residing at the well-known Internet port
.IR inport .
.PP
If the call succeeds, a socket of type SOCK_STREAM
is returned to the caller, and given to the remote
command as 
.B stdin
and
.BR stdout .
If
.I fd2p
is non-zero, then an auxiliary channel to a control
process will be set up, and a descriptor for it will be placed
in
.IR *fd2p .
The control process will return diagnostic
output from the command (unit 2) on this channel, and will also
accept bytes on this channel as being UNIX signal numbers, to be
forwarded to the process group of the command.
If
.I fd2p
is 0, then the 
.B stderr
(unit 2 of the remote
command) will be made the same as the 
.B stdout
and no
provision is made for sending arbitrary signals to the remote process,
although you may be able to get its attention by using out-of-band data.
.PP
The protocol is described in detail in
.IR rshd (8C).
.PP
The
.I rresvport
routine is used to obtain a socket with a privileged
address bound to it.  This socket is suitable for use
by 
.I rcmd
and sevral other routines.  Privileged addresses consist
of a port in the range 0 to 1023.  Only the super-user
is allowed to bind an address of this sort to a socket.
.PP
.I Ruserok
takes a remote host's name, as returned by a
.IR gethostent (3N)
routine, two user names and a flag indicating if
the local user's name is the super-user.  It then
checks the files 
.I /etc/hosts.equiv
and, possibly, 
.I .rhosts
in the current working directory (normally the local
user's home directory) to see if the request for
service is allowed.  A 1 is returned if the machine
name is listed in the ``hosts.equiv'' file, or the
host and remote user name are found in the ``.rhosts''
file; otherwise 
.I ruserok
returns 0.  If the
.I superuser
flag is 1, the checking of the ``host.equiv'' file is
bypassed.
.SH SEE ALSO
rlogin(1C),
rsh(1C),
rexec(3X),
rexecd(8C),
rlogind(8C),
rshd(8C)
net_network
for malformed requests.
.SH BUGS
The problunix/man/man3/shutdown.3n                                                                              444     322     145         1552  3621344676  10653                                                                                                                                                                                                                                                                                                                                                                      .TH SHUTDOWN 3N "" CMC
.UC 4
.SH NAME
shutdown \- shut down part of a full-duplex connection
.SH SYNOPSIS
.nf
.ft B
shutdown(s, how)
int s, how;
.fi
.SH DESCRIPTION
The
.I shutdown
call causes all or part of a full-duplex connection on
the socket associated with
.I s
to be shut down.
If \fIhow\fP is 0, then further receives will be disallowed.
If \fIhow\fP is 1, then further sends will be disallowed.
If \fIhow\fP is 2, then further sends and receives will be disallowed.
.SH DIAGNOSTICS
A 0 is returned if the call succeeds, \-1 if it fails.
.SH ERRORS
The call succeeds unless:
.TP 15
[EBADF]
.I S
is not a valid descriptor.
.TP 15
[ENOTSOCK]
.I S
is a file, not a socket.
.TP 15
[ENOTCONN]
The specified socket is not connected.
.SH NOTES
.I Shutdown
has local significance only;
no information is propogated to the remote host.
.SH "SEE ALSO"
connect(3N), socket(3N)

.IR rshd (8C)
server (among others).
.PP
.I Rcmd
looks up the host
.I *ahost
using
.IR gethostbyname (3N),
returning \-1 if the host does not exist.
unix/man/man3/socket.3n                                                                                444     322     145        12751  3621344677  10314                                                                                                                                                                                                                                                                                                                                                                      .TH SOCKET 3N "" CMC
.UC 4
.SH NAME
socket \- create an endpoint for communication
.SH SYNOPSIS
.nf
.ft B
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
s = socket(af, type, protocol)
int s, af, type, protocol;
.fi
.SH DESCRIPTION
.I Socket
creates an endpoint for communication and returns a descriptor.
.PP
The
.I af
parameter specifies an address format with which addresses specified
in later operations using the socket should be interpreted.  These
formats are defined in the include file
.IR <CMC/socket.h> .
The currently understood format is
.PP
.RS
.nf
.ta 1.25i 1.75i
AF_INET	(ARPA Internet addresses).
.br
.ta 1.25i 1.75i
AF_ETHER	(Ethernet link level addresses).
.fi
.RE
.PP
The socket has the indicated
.I type
which specifies the semantics of communication.  Currently
defined types are:
.PP
.RS
.nf
SOCK_STREAM
SOCK_DGRAM
SOCK_RAW
SOCK_SEQPACKET
SOCK_RDM
.fi
.RE
.PP
A SOCK_STREAM type provides sequenced, reliable,
two-way connection based byte streams with an out-of-band data
transmission mechanism.
A SOCK_DGRAM socket supports
datagrams (connectionless, unreliable messages of
a fixed (typically small) maximum length).
SOCK_RAW sockets provide access to internal network interfaces.
The types SOCK_RAW,
which is available only to the super-user, and
SOCK_SEQPACKET and SOCK_RDM, which are planned,
but not yet implemented, are not described here.
.PP
The
.I protocol
specifies a particular protocol to be used with the socket.
Normally only a single protocol exists to support a particular
socket type using a given address format.  However, it is possible
that many protocols may exist in which case a particular protocol
must be specified in this manner.  The protocol number to use is
particular to the \*(lqcommunication domain\*(rq in which communication
is to take place; see
.IR services (3N)
and
.IR protocols (3N).
.PP
Sockets of type SOCK_STREAM
are full-duplex byte streams, similar
to pipes.  A stream socket must be in a
.I connected
state before any data may be sent or received
on it.  A connection to (   (   another socket is created with a
.IR connect (3N)
call.  Once connected, data may be transferred using
.IR read (2)
and
.IR write (2)
calls or some variant of the 
.IR send (3N)
and
.IR recv (3N)
calls.  When a session has been completed a
.IR close (2)
may be performed.
Out-of-band data may also be transmitted as described in
.IR send (3N)
and received as described in
.IR recv (3N).
.PP
The communications protocols used to implement a
SOCK_STREAM insure that data
is not lost or duplicated.  If a piece of data for which the
peer protocol has buffer space cannot be successfully transmitted
within a reasonable length of time, then
the connection is considered broken and calls
will indicate an error with
\-1 returns and with ETIMEDOUT as the specific code
in the global variable errno.
The protocols optionally keep sockets \*(lqwarm\*(rq by
forcing transmissions
roughly every minute in the absence of other activity.
An error is then indicated if no response can be
elicited on an otherwise
idle connection for a extended period (e.g. 5 minutes).
A SIGPIPE signal is raised if a process sends
on a broken stream; this causes naive processes,
which do not handle the signal, to exit.
.PP
SOCK_DGRAM and SOCK_RAW
sockets allow sending of datagrams to correspondents
named in
.IR send (3N)
calls.  It is also possible to receive datagrams at
such a socket with
.IR recv (3N).
.PP
An 
.IR fcntl (2)
call can be used to specify a process group to receive
a SIGURG signal when the out-of-band data arrives.
.PP
The operation of sockets is controlled by socket level
.IR options .
These options are defined in the file
.RI < CMC/socket.h >
and explained below.  
.I Setsockopt
and
.IR getsockopt (3N)
are used to set and get options, respectively.
.PP
.RS
.DT
.nf
SO_DEBUG 		turn on recording of debugging information
SO_REUSEADDR	allow local address reuse
SO_LINGER 		linger on close if data present
SO_DONTLINGER	do not linger on close
.fi
.RE
.PP
SO_DEBUG enables debugging in the underlying protocol modules.
SO_REUSEADDR indicates the rules used in validating addresses supplied
in a
.IR bind (3N)
call should allow reuse of local addresses.
SO_LINGER
and SO_DONTLINGER control the actions taken when unsent messags
are queued on socket and a 
.IR close (2)
is performed.
If the socket promises reliable delivery of data and SO_LINGER is set,
the system will block the process on the 
.I close
attempt until it is able to transmit the data or until it decides it
is unable to deliver the information (a timeout period, termed the
linger interval, is specified in the
.IR setsockopt 
call when SO_LINGER is requested). 
If SO_DONTLINGER is specified and a 
.I close
is issued, the system will process the close in a manner which allows
the process to continue as quickly as possible.
.SH "RETURN VALUE
A \-1 is returned if an error occurs, otherwise the return
value is a descriptor referencing the socket.
.SH "ERRORS
The \fIsocket\fP call fails if:
.TP 20
[EAFNOSUPPORT]
The specified address family is not supported in this version
of the system.
.TP 20
[ESOCKTNOSUPPORT]
The specified socket type is not supported in this address family.
.TP 20
[EPROTONOSUPPORT]
The specified protocol is not supported.
.TP 20
[EMFILE]
The per-process descriptor table is full.
.TP 20
[ENOBUFS]
No buffer space is available.  The socket cannot be created.
.SH SEE ALSO
accept(3N), bind(3N), connect(3N), getsockname(3N), getsockopt(3N),
ioctl(2), listen(3N), recv(3N),
send(3N), shutdown(3N).
.SH BUGS
The use of keepalives is a questionable feature for this layer.
r |more\*(rq.
.TP
3)
Faunix/man/man3/recv.3n                                                                                  444     322     145         4243  3621344677   7740                                                                                                                                                                                                                                                                                                                                                                      .TH RECV 3N "" CMC
.UC 4
.SH NAME
recv, recvfrom \- receive a message from a socket
.SH SYNOPSIS
.nf
.ft B
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
cc = recv(s, buf, len, flags)
int cc, s;
char *buf;
int len, flags;
.PP
.ft B
cc = recvfrom(s, buf, len, flags, from, fromlen)
int cc, s;
char *buf;
int len, flags;
struct sockaddr *from;
int *fromlen;
.ft R
.SH DESCRIPTION
.IR Recv ,
and
.I recvfrom
are used to receive messages from a socket.
.PP
The 
.I recv
call may be used only on a 
.I connected
socket (see
.IR connect (3N)),
while 
.I recvfrom
may be used to receive data on a socket whether
it is in a connected state or not.
.PP
If
.I from
is non-zero, the source address of the message is filled in.
.I Fromlen
is a value-result parameter, initialized to the size of
the buffer associated with
.IR from ,
and modified on return to indicate the actual size of the
address stored there.
The length of the message is returned in
.IR cc .
If a message is too long to fit in the supplied buffer,
excess bytes may be discarded depending on the type of socket
the message is received from; see
.IR socket (3N).
.PP
If no messages are available at the socket, the
receive call waits for a message to arrive, unless
the socket is nonblocking (see
.IR fcntl (3))
in which case a
.I cc
of \-1 is returned with the external variable errno
set to EWOULDBLOCK.
.PP
The
.I flags
argument to a recv call is formed by 
.IR or 'ing
one or more of the values,
.PP
.nf
.RS
.DT
#define	MSG_PEEK	0x1	/* peek at incoming message */
#define	MSG_OOB	0x2	/* process out-of-band data */
.RE
.fi
.SH "RETURN VALUE
These calls return the number of bytes received, or \-1
if an error occurred.
.SH ERRORS
The calls fail if:
.TP 20
[EBADF]
The argument \fIs\fP is an invalid descriptor.
.TP 20
[ENOTSOCK]
The argument \fIs\fP is not a socket.
.TP 20
[EWOULDBLOCK]
The socket is marked non-blocking and the receive operation
would block.
.TP 20
[EINTR]
The receive was interrupted by delivery of a signal before
any data was available for the receive.
.TP 20
[EFAULT]
The data was specified to be received into a non-existent
or protected part of the process address space.
.SH SEE ALSO
read(2), send(3N), socket(3N)
sent messags
are queued on socket and a 
.IR close (2)
is performed.
If the socket promises reliable delivery of data and SO_LINGER is set,
the system will block the process on the 
.I close
attempt until it is able to transmit the data or until it decides it
is unable to deliver the information (a timeout period, termed the
linger interval, is spunix/man/man3/send.3n                                                                                  444     322     145         3571  3621344700   7720                                                                                                                                                                                                                                                                                                                                                                      .TH SEND 3N "" CMC
.UC 4
.SH NAME
send, sendto \- send a message from a socket
.SH SYNOPSIS
.nf
.ft B
#include <CMC/types.h>
#include <CMC/socket.h>
.PP
.ft B
cc = send(s, msg, len, flags)
int cc, s;
char *msg;
int len, flags;
.PP
.ft B
cc = sendto(s, msg, len, flags, to, tolen)
int cc, s;
char *msg;
int len, flags;
struct sockaddr *to;
int tolen;
.fi
.SH DESCRIPTION
.IR Send ,
and
.I sendto
are used to transmit a message to another socket.
.I Send
may be used only when the socket is in a 
.I connected
state, while 
.I sendto
may be used at any time.
.PP
The address of the target is given by
.I to
with 
.I tolen
specifying its size.
The length of the message is given by
.IR len .
If the message is too long to pass atomically through the
underlying protocol, then the error EMSGSIZE is returned, and
the message is not transmitted.
.PP
No indication of failure to deliver is implicit in a
.IR send .
Return values of \-1 indicate some locally detected errors.
.PP
If no message space is available at the socket to hold
the message to be transmitted, then
.I send
normally blocks, unless the socket has been placed in
non-blocking i/o mode.
.PP
The
.I flags
parameter may be set to SOF_OOB to send \*(lqout-of-band\*(rq
data on sockets which support this notion (e.g. SOCK_STREAM).
.PP
See 
.IR recv (3N)
for a description of the
.I msghdr
structure.
.SH "RETURN VALUE
The call returns the number of characters sent, or \-1
if an error occurred.
.SH "ERRORS
.TP 20
[EBADF]
An invalid descriptor was specified.
.TP 20
[ENOTSOCK]
The argument \fIs\fP is not a socket.
.TP 20
[EFAULT]
An invalid user space address was specified for a parameter.
.TP 20
[EMSGSIZE]
The socket requires that message be sent atomically,
and the size of the message to be sent made this impossible.
.TP 20
[EWOULDBLOCK]
The socket is marked non-blocking and the requested operation
would block.
.SH SEE ALSO
recv(3N), socket(3N)
ation
would block.
.TP 20
[EINTR]
The receive was interrupted by delivery of a signal before
any data was available for the receive.
.Tunix/man/man4/                                                                                         750     322     145            0  3621344706   6436                                                                                                                                                                                                                                                                                                                                                                      unix/man/man4/ether.4f                                                                                 444     322     145         2302  3621344702  10061                                                                                                                                                                                                                                                                                                                                                                       (   (  .TH ETHER 4F "" CMC
.SH NAME
ether - ETHERNET raw socket interface
.SH SYNOPSIS
.B
# include <CMC/longnames.h>
.br
.B
# include <CMC/socket.h>
.br
.B
# include <CMC/eth.h>
.SH DESCRIPTION
The Ethernet family provides support for the
SOCK_RAW socket type.
It permits user programs to produce and consume
ETHERNET packets of any specified type.
.SH ADDRESSING
ETHERNET address are six byte quantities, stored in
network standard format.
The include file
.I <CMC/eth.h>
defines the following address structure:
.RS 5

typedef
.br
struct en_addr {
.br
	char	ena_addr[6];
.br
} en_addr;

typedef
.br
struct sockaddr_eth {
.br
	short	sen_family;
.br
	u_short	sen_type;		/* Ethernet type code */
.br
	en_addr	sen_addr;
.br
	char	sen_zero[4];
.br
} sockaddr_eth;
.RE
.br

Sockets may be bound to the type ETHTYPE_ANY to consume
all types other than those specifically bound to some
other socket.
.SH PROTOCOLS
No standard protocols utilize this interface.
.SH SEE ALSO
ether(4P)
.SH CAVEAT
Normally,
only the single most recently received datagram
is retained for a socket which does not have
an outstanding
.I read(2)
request.
.PP
Users, even in promiscuous mode, can not receive IP (type 0x800)
or ARP (type 0x806) packets.
band\*(rq
data on sockets which support this notion (e.g. SOCK_STREAM).
.PP
See 
.IR recv (3N)
for a description of the
.I msghdr
structure.
.SH "RETURN VALUE
The call returns the number of characters sent, or \-1
if an error occurred.
.SH "ERRORS
.TP 20
[EBADF]
An invalid descriptor was specified.
.TP 20
[ENOTSOCK]
unix/man/man4/ether.4p                                                                                 444     322     145        20547  3621344703  10127                                                                                                                                                                                                                                                                                                                                                                      .TH ETHER 4P "" CMC
.SH NAME
eth - ENP interface to ETHERNET
.SH SYNOPSIS
# include <CMC/socket.h>
.br
# include <CMC/eth.h>

s = socket (AF_ETHER, SOCK_RAW, 0);
.br
sen.sen_type = <Ethernet packet type>;
.br
bind (s, &sen, sizeof (sen));

sockaddr_eth sen = {AF_ETHER};
.SH DESCRIPTION
This section describes low\-level access to the ETHERNET \*(Tm as provided by
an ENP \*(Tm and its associated LANCE.
It does not describe the operation of the ENP or the LANCE,
nor describe the ETHERNET communication protocol.
See the documents referenced below for such information.

This interface does not do any protocol manipulation.
It is the responsibility of the user to set up and interpret
ETHERNET-style datagrams.
Each socket is bound to a single ETHERNET packet type;
no more than one socket may be bound to a single type.

Data movement is performed using the
.IR read (2)
and
.IR write (2)
system calls.
.PP
.I Read
and
.I write
manipulate complete ETHERNET datagram packets.
Each call to
.I write
should supply a complete, fully formatted datagram
for writing to the ETHERNET.
The datagram must contain the appropriate type field;
the ETHERNET source address field
will be filled in by the ENP unless the USEADDR option
has been set (see below).
Calls to 
.I read
should supply a buffer large enough to contain a
complete datagram.
If the supplied buffer is not big enough to hold the
entire datagram (including 4 bytes of CRC), the datagram is truncated and the
excess data is lost.
.PP
.I Getsockopt
and
.I setsockopt
calls provide access to LANCE mode information and
access to ENP statistics.
.I Getsockopt
calls to access LANCE information have the syntax:

	getsockopt (s, SOL_ETHER, command, &arg, &size);
	long int size;
.br

.I Size
is initially set by the caller to
.I sizeof (arg),
upon return it will be set to the actual number of
bytes written to
.I arg.
The commands to
.I getsockopt
are defined in the include file
.B <CMC/eth.h>
They are:
.TP
EIOCGETMODE
Sets
.I arg
to the contents of the LANCE control and status register.
.I Arg
is a
.B short.
Bits in this register are:
.RS 5
.TP
ANYERROR (0x8000)
The OR of
BABBLE,
COLLISION,
MISS,
and
MEMERR.
.TP
BABBLE (0x4000)
Transmitter Timeout Error.
Indicates that the transmitter has been on the channel
longer than the time required to send the maximum length packet.
BABBLE
will be set after 1519 bytes have been transmitted.
.TP
COLLISION (0x2000)
Indicates that the collision input to the LANCE failed to
activate within 2us after a LANCE-initiated
transmission was completed.
The collision after transmission is a transceiver test feature.
.TP
MISS (0x1000)
Missed Packet.
Set when the receiver loses a packet because it does not own a
receive buffer and the silo has overflowed, indicating loss of data.
.TP
MEMERR (0x0800)
Memory Error.
Set when the LANCE is the Bus Master and has not received
READY within 25.6us after asserting the address on the DAL
lines.
When a Memory Error is detected, the receiver and transmitter
are turned off.
.TP
RCVINT (0x0400)
Receiver Interrupt.
Set after the LANCE updates an entry in the
receive descriptor ring.
.TP
XMITINT (0x0200)
Transmitter Interrupt.
Set after the LANCE updates an entry in the transmit descriptor ring.
.TP
INITDONE (0x0100)
Initialization Done.
Indicates that the LANCE has completed the
initialization procedure started by setting the
INITIALIZE
bit.
When
INITDONE
is set, the LANCE has read the initializaion block from
memory and has stored the new parameters.
.TP
INTPENDING (0x0080)
Interrupt Flag.
When set, indicates that one or more of the following
conditions has occured:
BABBLE,
MISS,
MEMERR,
RCVINT,
XMITINT,
or
INITDONE.
.TP
INTENABLE (0x0040)
Interrupt Enable.
Allows the LANCE to interrupt the ENP.
.TP
RCVRON (0x0020)
Receiver On.
Indicates that the receiver is enabled.
.TP
XMITON (0x0010)
Transmitter On.
Indicates that the transmitter is enabled.
.TP
DEMANDXMIT (0x0008)
Transmit Demand.
When set causes the LANCE to access the transmit
descriptor ring without waiting for the polltime interval to elapse.
DEMANDXMIT
is Write-With-1 only, and is cleared by the microcode after it is used.
.TP
STOPPED (0x0004)
Disables the LANCE from all external activity and clears all
the internal logic.
The LANCE remains inactive, and 
STOPPED
remains asserted,
until the
STARTED
or
INITIALIZE
bit is set.
.TP
STARTED (0x0002)
Enables the LANCE to send and receive packets, perform
direct memory access, and do buffer management.
.TP
INITIALIZE (0x0001)
Causes the LANCE to begin the initialization procedure and 
access the initialization block.
.RE
.TP
EIOCGETBUF
Returns the number of buffers which will be saved.
Note this is not necessarily the number which are currently saved.
.I Arg
is a
.BR *int .
.TP
EIOCGETSTAT
.TP
EIOCGETSTATCLR
.I Arg
is a
.B struct 
.BR eth_io_stat .
The
.B eth_io_stat
structure, described below, consists of a set of counters
kept by the ENP.
The values of these counters reflect the number of time the
named event has been reported by the LANCE since the last
EIOCCLRSTAT
or
EIOCGETSTATCLR
command.
Both
EIOCGETSTAT and EIOCGETSTATCLR
copy the current statistic counters to
.I arg;
EIOCGETSTATCLR
then resets them to 0.
.RE
.PP
.I Setsockopt
calls are expressed:
.br
	setsockopt (s, SOL_ETHER, command, &arg, sizeof (arg))

The
.I setsockopt
commands are:
.TP
EIOCSETMODE
Allows the user to set the LANCE mode register.
.I Arg
is
.B short int.
Settable bits are:
.RS 5
.TP
PROMISCUOUS (0x8000)
Indicates that the ENP will receive all messages on the media.
Note that the socket from
which this command is issued will still only receive
datagrams with a type field matching that bound to the socket.
.TP
USEADDR (0x2000)
Disables the ENP from setting the source address field of
datagrams written from this socket.
.TP
LOOPBACK (0x0004)
Loopback Mode.
When set, LANCE is in loopback mode.
This allows simultaneous send and receive of up to 32 byte packets.
The choice of internal or external loopback is controlled by
the setting of
LOOPINTERN.
.TP
LOOPINTERN (0x0040)
Internal loopback.
When
LOOPBACK
and
LOOPINTERN
are both set, indicates internal loopback mode.
.TP
DONTRETRY (0x0020)
Disable Retries.
When on, the LANCE will not attempt to retransmit upon
collision detection.
When this bit is one, Retry Failure is indicated (in
.I errno
as described above)
upon a single collision detection.
.TP
FRCECOLLIDE (0x0010)
Force Collision.
Only valid in internal loopback mode.
When set, a collision will be forced upon the next transmission.
.TP
NOXMITCRC (0x0008)
Disable Transmit CRC.
Inhibits generation of CRC for transmitted message.
.TP
NOXMITTER (0x0002)
Disable Transmitter.
When set inhibits access to the transmit
descriptor ring, so no transmittion will occur.
.TP
NORECVER (0x0001)
Disable Receiver.
When set inhibits access to the receive descriptor ring, so
no receives will occur.
.RE
.TP
EIOCCLRSTAT
.RS 5
Clears the ENP statistics counters.
This command requires no arguments, so
.B arg
and
.B sizeof(arg)
should both be 0.
.RE
.PP
The structure
.B eth_io_stat
is:

	struct eth_io_stat {
.br
		unsigned long e_xmit_successful;
.br
				/* successful transmissions */
.br
		unsigned long e_mult_retry;
.br
				/* multiple retries on xmit */
.br
		unsigned long e_one_retry;
.br
				/* single retries */
.br
		unsigned long e_fail_retry;
.br
				/* too many retries */
.br
		unsigned long e_deferrals;
.br
				/* trasmission delayed due to active
.br
				   medium */
.br
		unsigned long e_xmit_buff_err;
.br
				/* xmit data chaining failed;
.br
				   "can't happen" */
.br
		unsigned long e_silo_underrun;
.br
				/* xmit data fetch failed */
.br
		unsigned long e_late_coll;
.br
				/* collision after xmit */
.br
		unsigned long e_lost_carrier;
.br
		unsigned long e_babble;
.br
				/* xmit length > 1518 */
.br
		unsigned long e_collision;
.br
		unsigned long e_xmit_mem_err;
.br
		unsigned long e_rcv_successful;
.br
				/* good receptions */
.br
		unsigned long e_rcv_missed;
.br
				/* no recv buff available */
.br
		unsigned long e_crc_err;
.br
				/* checksum failed */
.br
		unsigned long e_frame_err;
.br
				/* crc error AND
.br
				   data length != 0 mod 8 */
.br
		unsigned long e_rcv (   (  _buff_err;
.br
				/* rcv data chain failure;
.br
				   "can't happen" */
.br
		unsigned long e_silo_overrun;
.br
				/* receive data store failed */
.br
		unsigned long e_rcv_mem_err;
.br
	};
.SH FILES
<CMC/socket.h>
.br
<CMC/eth.h>
.br
/dev/socket/s*
.SH SEE ALSO
socket(3N), bind(3N), close(2), read(2), write(2), fcntl(2), getsockopt(3N),
setsockopt(3N)
ed by
an ENP \*(Tm and its associated LANCE.
It does not describe the operation of the ENP or the LANCE,
nor describe the ETHERNET communication protocolunix/man/man4/inet.4f                                                                                  444     322     145         3242  3621344703   7716                                                                                                                                                                                                                                                                                                                                                                      .TH INET 4F "" CMC
.UC  4
.SH NAME
inet \- Internet protocol family
.SH SYNOPSIS
.B #include <CMC/types.h>
.br
.B #include <CMC/in.h>
.SH DESCRIPTION
.de _d
.if t .ta .6i 2.1i 2.6i
.\" 2.94 went to 2.6, 3.64 to 3.30
.if n .ta .84i 2.6i 3.30i
..
.de _f
.if t .ta .5i 1.25i 2.5i
.\" 3.5i went to 3.8i
.if n .ta .7i 1.75i 3.8i
..
The Internet protocol family is a collection of protocols
layered atop the
.I Internet Protocol
(IP) transport layer, and utilizing the Internet address format.
The Internet family provides protocol support for the
SOCK_STREAM socket type.
.SH ADDRESSING
Internet addresses are four byte quantities, stored in
network standard format.
The include file
.RI < CMC/in.h >
defines this address
as a discriminated union.
.PP
Sockets bound to the Internet protocol family utilize
the following addressing structure,
.sp 1
.nf
._f
struct sockaddr_in {
	short	sin_family;
	u_short	sin_port;
	struct	in_addr sin_addr;
	char	sin_zero[8];
};
.sp 1
.fi
.SH PROTOCOLS
The Internet protocol family is comprised of
the IP transport protocol, Internet Control
Message Protocol (ICMP), Transmission Control
Protocol (TCP), and User Datagram Protocol (UDP).
TCP is used to support the SOCK_STREAM
abstraction while UDP is used to support the SOCK_DGRAM
abstraction.  A raw interface to IP is available
by creating an Internet socket of type SOCK_RAW.
The ICMP message protocol is not directly accessible.
.SH NOTES
UDP and raw IP are not yet supported.
.SH SEE ALSO
tcp(4P), ip(4P), udp(4P)
.SH CAVEAT
The Internet protocol support is subject to change as
the Internet protocols develop.  Users should not depend
on details of the current implementation, but rather
the services exported.
nd, &arg, &size);
	long int size;
.br

.I Size
is initially set by the caller to
.I sizeof (arg),
upon return it will be set to the actual number of
bytes written to
.I arg.
The commands to
.I getsockopt
are defined in the include file
.B <CMC/eth.h>
They are:
.TP
EIOCGETMODE
Sets
.I arg
to the contents of the LANCE control and status register.
.I unix/man/man4/intro.4n                                                                                 444     322     145         6600  3621344704  10124                                                                                                                                                                                                                                                                                                                                                                      .TH INTRO 4N "" CMC
.UC 4
.SH NAME
networking \- introduction to networking facilities
.SH SYNOPSIS
.nf
.ft B
#include <CMC/socket.h>
.fi R
.fi
.SH DESCRIPTION
.de _d
.if t .ta .6i 2.1i 2.6i
.\" 2.94 went to 2.6, 3.64 to 3.30
.if n .ta .84i 2.6i 3.30i
..
.de _f
.if t .ta .5i 1.25i 2.5i
.\" 3.5i went to 3.8i
.if n .ta .7i 1.75i 3.8i
..
This section briefly describes the networking facilities
available in the system.
Documentation in this part of section
4 is broken up into three areas:
.IR protocol-families ,
.IR protocols ,
and
.IR "network interfaces" .
Entries describing a protocol-family are marked ``4F'',
while entries describing protocol use are marked ``4P''.
Hardware support for network interfaces are found
among the standard ``4'' entries.
.PP
All network protocols are associated with a specific
.IR protocol-family .
A protocol-family provides basic services to the protocol
implementation to allow it to function within a specific
network environment.  These services may include 
packet fragmentation and reassembly, routing, addressing, and 
basic transport.  A protocol-family may support multiple
methods of addressing, though the current protocol implementations
do not.  A protocol-family is normally comprised of a number
of protocols, one per
.IR socket (3N)
type.  It is not required that a protocol-family support
all socket types.  A protocol-family may contain multiple
protocols supporting the same socket abstraction. 
.PP
A protocol supports one of the socket abstractions detailed
in
.IR socket (3N).
A specific protocol may be accessed either by creating a
socket of the appropriate type and protocol-family, or
by requesting the protocol explicitly when creating a socket.
Protocols normally accept only one type of address format,
usually determined by the addressing structure inherent in
the design of the protocol-family/network architecture.
Certain semantics of the basic socket abstractions are
protocol specific.  All protocols are expected to support
the basic model for their particular socket type, but may,
in addition, provide non-standard facilities or extensions
to a mechanism.  For example, a protocol supporting the
SOCK_STREAM
abstraction may allow more than one byte of out-of-band
data to be transmitted per out-of-band message.
.PP
A network interface is similar to a device interface.
Network interfaces comprise the lowest layer of the
networking subsystem, interacting with the actual transport
hardware.  An interface may support one or more protocol
families, and/or address formats.
The SYNOPSIS section of each network interface
entry gives a sample specification
of the related drivers for use in providing
a system description.
The DIAGNOSTICS section lists messages which may appear on the console
and in the system error log
.I /usr/adm/messages
due to errors in device operation.
.SH PROTOCOLS
The system currently supports only the DARPA Internet
protocols fully.  
Consult the appropriate manual pages in this section for more
information regarding the support for the protocol family.
.SH ADDRESSING
Associated with each protocol family is an address
format.  The following address formats are used by the system:
.sp 1
.nf
._d
#define	AF_UNIX	1	/* local to host (pipes, portals) */
#define	AF_INET	2	/* internetwork: UDP, TCP, etc. */
#define	AF_IMPLINK	3	/* arpanet imp addresses */
#define	AF_PUP	4	/* pup protocols: e.g. BSP */
.fi
.SH SEE ALSO
socket(3N),
ioctl(2),
intro(4)
memory and has stored the new parameters.
.TP
INTPENDING (0x0080)
Interrupt Flag.
When set, indicates that one or more of the founix/man/man4/pty.4                                                                                    444     322     145         4464  3621344704   7435                                                                                                                                                                                                                                                                                                                                                                      .TH PTY 4 "" CMC
.UC 4
.SH NAME
pty \- pseudo terminal driver
.SH SYNOPSIS
.B "#include <CMC/pty.h>"
.SH DESCRIPTION
The
.I pty
driver provides support for a device-pair termed a
.IR "pseudo terminal" .
A pseudo terminal is a pair of character devices, a
.I master
device and a
.I slave
device.  The slave device provides processes
an interface identical
to that described in
.IR tty (4).
However, whereas all other devices which provide the 
interface described in
.IR tty (4)
have a hardware device of some sort behind them, the slave
device has, instead, another process manipulating
it through the master half of the pseudo terminal.
That is, anything written on the master device is
given to the slave device as input and anything written
on the slave device is presented as input on the master
device.
.PP
In configuring, if no optional ``count'' is given in
the specification, 16 pseudo terminal pairs are configured.
.PP
The following 
.I ioctl
calls apply only to pseudo terminals:
.TP
TIOCPKT
Enable/disable 
.I packet
mode.  Packet mode is enabled by specifying (by reference)
a nonzero parameter and disabled by specifying (by reference)
a zero parameter.  When applied to the master side of a pseudo
terminal, each subsequent 
.I read 
from the terminal will return data written on the slave part of
the pseudo terminal preceded by a zero byte (symbolically
defined as TIOCPKT_DATA), or a single byte reflecting control
status information.  In the latter case, the byte is an inclusive-or
of zero or more of the bits:
.RS
.TP
TIOCPKT_FLUSHREAD
whenever the read queue for the terminal is flushed.
.TP
TIOCPKT_FLUSHWRITE
whenever the write queue for the terminal is flushed.
.TP
TIOCPKT_STOP
whenever output to the terminal is stopped a la ^S.
.TP
TIOCPKT_START
whenever output to the terminal is restarted.
.TP
TIOCPKT_DOSTOP
whenever 
.I t_stopc
is ^S
and 
.I t_startc
is ^Q.
.TP
TIOCPKT_NOSTOP
whenever the start and stop characters are not ^S/^Q.
.RE
.IP
This mode is used by
.IR rlogin (1C)
and
.IR rlogind (8C)
to implement a remote-echoed, locally ^S/^Q flow-controlled
remote login with proper back-flushing of output; it can be
used by other similar programs.
.SH FILES
.DT
/dev/pty[p-r][0-9a-f]	master pseudo terminals
.br
/dev/tty[p-r][0-9a-f]	slave pseudo terminals
.SH DIAGNOSTICS
None.
.SH BUGS
It is not possible to send an EOT.
nterfaces comprise the lowest layer of the
networking subsystem, interacting with the actual transport
hardware.  An interface may support one or more protocol
families, and/or address formats.
The SYNOPS (   (  unix/man/man4/tcp.4p                                                                                   444     322     145         5357  3621344705   7572                                                                                                                                                                                                                                                                                                                                                                      .TH TCP 4P "" CMC
.UC 4
.SH NAME
tcp \- Internet Transmission Control Protocol
.SH SYNOPSIS
.B #include <CMC/socket.h>
.br
.B #include <CMC/in.h>
.PP
.B s = socket(AF_INET, SOCK_STREAM, 0);
.SH DESCRIPTION
The TCP protocol provides reliable, flow-controlled, two-way
transmission of data.  It is a byte-stream protocol used to
support the SOCK_STREAM abstraction.  TCP uses the standard
Internet address format and, in addition, provides a per-host
collection of \*(lqport addresses\*(rq.  Thus, each address is composed
of an Internet address specifying the host and network, with
a specific TCP port on the host identifying the peer entity.
.PP
Sockets utilizing the tcp protocol are either \*(lqactive\*(rq or
\*(lqpassive\*(rq.  Active sockets initiate connections to passive
sockets.  By default TCP sockets are created active; to create a
passive socket the
.IR listen (3N)
system call must be used
after binding the socket with the
.IR bind (3N)
system call.  Only
passive sockets may use the 
.IR accept (3N)
call to accept incoming connections.  Only active sockets may
use the
.IR connect (3N)
call to initiate connections.
.PP
Passive sockets may \*(lqunderspecify\*(rq their location to match
incoming connection requests from multiple networks.  This
technique, termed \*(lqwildcard addressing\*(rq, allows a single
server to provide service to clients on multiple networks.
To create a socket which listens on all networks, the Internet
address INADDR_ANY
must be bound.  The TCP port may still be specified
at this time; if the port is not specified the system will assign one.
Once a connection has been established the socket's address is
fixed by the peer entity's location.   The address assigned the
socket is the address associated with the network interface
through which packets are being transmitted and received.  Normally
this address corresponds to the peer entity's network.
.SH DIAGNOSTICS
A socket operation may fail with one of the following errors returned:
.TP 20
[EISCONN]
when trying to establish a connection on a socket which
already has one;
.TP 20
[ENOBUFS]
when the system runs out of memory for
an internal data structure;
.TP 20
[ETIMEDOUT]
when a connection was dropped
due to excessive retransmissions;
.TP 20
[ECONNRESET]
when the remote peer
forces the connection to be closed;
.TP 20
[ECONNREFUSED]
when the remote
peer actively refuses connection establishment (usually because
no process is listening to the port);
.TP 20
[EADDRINUSE]
when an attempt
is made to create a socket with a port which has already been
allocated;
.TP 20
[EADDRNOTAVAIL]
when an attempt is made to create a 
socket with a network address for which no network interface
exists.
.SH SEE ALSO
intro(4N), inet(4F)
.SH BUGS
It should be possible to send and receive TCP options.
 /usr/adm/messages
due to errors in device operation.
.SH PROTOCOLS
The system currently supports only the DARPA Internet
protocols fully.  
Consult the appropriate manual pages in this section for more
information regarding the support for the protocol family.
.SH ADDRESSunix/man/man4/ip.4p                                                                                    444     322     145         3266  3621344705   7411                                                                                                                                                                                                                                                                                                                                                                      .TH IP 4P "" CMC
.UC 4
.SH NAME
ip \- Internet Protocol
.SH SYNOPSIS
.B #include <CMC/socket.h>
.br
.B #include <CMC/in.h>
.PP
.B s = socket(AF_INET, SOCK_RAW, 0);
.SH DESCRIPTION
IP is the transport layer protocol used
by the Internet protocol family.  It may be accessed
through a \*(lqraw socket\*(rq when developing new protocols, or
special purpose applications.  IP sockets are connectionless,
and are normally used with the
.I sendto 
and
.I recvfrom 
calls, though the
.IR connect (3N)
call may also be used to fix the destination for future
packets (in which case the 
.IR read (2)
or
.IR recv (3N)
and 
.IR write (2)
or
.IR send (3N)
system calls may be used).
.PP
Outgoing packets automatically have an IP header prepended to
them (based on the destination address and the protocol
number the socket is created with).
Likewise, incoming packets have their IP header stripped
before being sent to the user.
.SH DIAGNOSTICS
A socket operation may fail with one of the following errors returned:
.TP 15
[EISCONN]
when trying to establish a connection on a socket which
already has one, or when trying to send a datagram with the destination
address specified and the socket is already connected;
.TP 15
[ENOTCONN]
when trying to send a datagram, but
no destination address is specified, and the socket hasn't been
connected;
.TP 15
[ENOBUFS]
when the system runs out of memory for
an internal data structure;
.TP 15
[EADDRNOTAVAIL]
when an attempt is made to create a 
socket with a network address for which no network interface
exists.
.SH SEE ALSO
send(3N), recv(3N), intro(4N), inet(4F)
.SH BUGS
One should be able to send and receive ip options.
.PP
The protocol should be settable after socket creation.
e
socket is the address associated with the network interface
through which packets are being transmitted and received.  Normally
this address corresponds to the peer entity's network.
.SH DIAGNOSTICS
A socket operation may fail with one of the following errors returned:
.TP 20
[EISCONN]
when trying to establish a connection on unix/man/man4/udp.4p                                                                                   444     322     145         3551  3621344706   7567                                                                                                                                                                                                                                                                                                                                                                      .TH UDP 4P "" CMC
.UC 4
.SH NAME
udp \- Internet User Datagram Protocol
.SH SYNOPSIS
.B #include <CMC/socket.h>
.br
.B #include <CMC/in.h>
.PP
.B s = socket(AF_INET, SOCK_DGRAM, 0);
.SH DESCRIPTION
UDP is a simple, unreliable datagram protocol which is used
to support the SOCK_DGRAM abstraction for the Internet
protocol family.  UDP sockets are connectionless, and are
normally used with the
.I sendto 
and
.IR recvfrom 
calls, though the
.IR connect (3N)
call may also be used to fix the destination for future
packets (in which case the 
.IR recv (3N)
or
.IR read (2)
and 
.IR send (3N)
or
.IR write (2)
system calls may be used).
.PP
UDP address formats are identical to those used by
TCP. In particular UDP provides a port identifier in addition
to the normal Internet address format.  Note that the UDP port
space is separate from the TCP port space (i.e. a UDP port
may not be \*(lqconnected\*(rq to a TCP port).  In addition broadcast
packets may be sent (assuming the underlying network supports
this) by using a reserved \*(lqbroadcast address\*(rq; this address
is network interface dependent.
.SH DIAGNOSTICS
A socket operation may fail with one of the following errors returned:
.TP 15
[EISCONN]
when trying to establish a connection on a socket which
already has one, or when trying to send a datagram with the destination
address specified and the socket is already connected;
.TP 15
[ENOTCONN]
when trying to send a datagram, but
no destination address is specified, and the socket hasn't been
connected;
.TP 15
[ENOBUFS]
when the system runs out of memory for
an internal data structure;
.TP 15
[EADDRINUSE]
when an attempt
is made to create a socket with a port which has already been
allocated;
.TP 15
[EADDRNOTAVAIL]
when an attempt is made to create a 
socket with a network address for which no network interface
exists.
.SH SEE ALSO
send(3N),
recv(3N),
intro(4N),
inet(4F)
work.
.SH DIAGNOSTICS
A socket operation may fail with one of the following errors returned:
.TP 20
[EISCONN]
when trying to establish a connection on unix/man/man5/                                                                                         750     322     145            0  3621344712   6434                                                                                                                                                                                                                                                                                                                                                                      unix/man/man5/hosts.5                                                                                  444     322     145         2310  3621344707   7752                                                                                                                                                                                                                                                                                                                                                                      .TH HOSTS 5  "" CMC
.SH NAME
hosts \- host name data base
.SH DESCRIPTION
The
.I hosts
file contains information regarding
the known hosts on the DARPA Internet.
For each host a single line should be present
with the following information:
.HP 10
official host name
.br
.ns
.HP 10
Internet address
.br
.ns
.HP 10
aliases
.PP
Items are separated by any number of blanks and/or
tab characters.  A ``#'' indicates the beginning of
a comment; characters up to the end of the line are
not interpreted by routines whic (   (  h search the file.
This file is normally created from the official host
data base maintained at the Network Information Control
Center (NIC), though local changes may be required
to bring it up to date regarding unofficial aliases
and/or unknown hosts.
.PP
Network addresses are specified in the conventional
``.'' notation using the \fIinet_addr\fP() routine
from the Internet address manipulation library,
.IR inet (3N).
Host names may contain any printable
character other than a field delimiter, newline,
or comment character.
.SH FILES
/etc/hosts
.SH "SEE ALSO"
gethostent(3N)
.SH BUGS
A name server should be used instead of a static file.
A binary indexed file format should be available for fast access.
 provides a port identifier in addition
to the normal Internet address format.  Note that the UDP port
space is separate from the TCP port space (i.e. a UDP port
may not be \*(lqconnected\*(rq to a TCP port).  In addition broadcast
packets may be sent (assuming the underlying network supports
this) by using a runix/man/man5/hosts.equiv.5                                                                            444     322     145         4175  3621344710  11107                                                                                                                                                                                                                                                                                                                                                                      .TH HOSTS.EQUIV 5  "" CMC
.SH NAME
hosts.equiv - names of hosts with "equivalent" user IDs
.SH DESCRIPTION
This file is used by
.IR rcp ,
.IR rsh ,
and
.I rlogin
to determine a set of hosts whose
users are considered to be "equivalent" to the
users of the same name on this system.
In an environment where a single organization might
have many systems used by a common set of users, it is
often the case that a single user will have the same ID on
many different systems.
The use of 
.I /etc/hosts.equiv
to specify the list of systems with common users, and common user IDs,
allows users access to the local system from each of these
remote systems without requiring passwords.
Further,
.I rsh
and
.I rcp
require that the user be considered equivalent on the local and remote
systems, or the operation is rejected.
.PP
.IR Rshd ,
used to support
.I rsh
and
.I rcp
requests, uses
.I /etc/hosts.equiv
in the following way.
When the connection is made,
.I rshd
gets the ID of the user on the remote ("calling") system.
It then looks up the remote user ID in the local
.I /etc/passwd
file.
If the remote user is not the super-user, then
.I /etc/hosts.equiv
is checked for the name of the remote host.
If it is found, the user is considered to be equivalent to
the user of the same local name, and the command proceeds.
If the host name is not found, or if the remote user is the
super-user, then
.I rshd
checks the file
.I .rhosts
in the login directory found in
.IR /etc/passwd .
If an entry is found for the remote host, or for this
local user name and remote host combination,
then the user is considered equivalent and the command proceeds.
If this test fails, the command is terminated.
.I Rlogin
uses these files in an analogous fashion.
.PP
The format of
.I /etc/hosts.equiv
is a list of host names
one per line.
The "primary" host name (i.e. the first one in
.IR /etc/hosts )
must be used.
.SH FILES
/etc/hosts.equiv
.SH "SEE ALSO"
rcp(1c), rlogin(1c), rsh(1c), rlogind(8c), rshd(8c),
rhosts(5)
.SH NOTES
On System V systems, users are required to enter their password
(if they have one) on the remote system.
This is due to the operation of
.I login
on these systems.
TIMEDOUT]
when a connection was dropped
due to excessive retransmissions;
.TP 20
[ECONNRESET]
when the remote peer
forces the connection to be closed;
.TP 20
[ECONNREFUSED]
when the remote
peer actively refuses connection establishment (usually because
no process is listening to the port);
.TP 20
[EADDRINUSE]
when an attempt
is made to create a socket with a port which has already beeunix/man/man5/networks.5                                                                               444     322     145         2372  3621344710  10470                                                                                                                                                                                                                                                                                                                                                                      .TH NETWORKS 5  "" CMC
.UC 4
.SH NAME
networks \- network name data base
.SH DESCRIPTION
The
.I networks
file contains information regarding
the known networks which comprise the DARPA Internet.
For each network a single line should be present with the following information:
.HP 10
official network name
.br
.ns
.HP 10
network number
.br
.ns
.HP 10
aliases
.PP
Items are separated by any number of blanks and/or tab characters.
A ``#'' indicates the beginning of a comment; characters up to the end of
the line are not interpreted by routines which search the file.
This file is normally created from the official network data base
maintained at the Network Information Control Center (NIC), though local
changes may be required to bring it up to date regarding unofficial aliases
and/or unknown networks.
.PP
Network number may be specified in the conventional
``.'' notation using the \fIinet_network\fP() routine
from the Internet address manipulation library,
.IR inet (3N).
Network names may contain any printable character other than a field
delimiter, newline, or comment character.
.SH FILES
/etc/networks
.SH "SEE ALSO"
getnetent(3N)
.SH BUGS
A name server should be used instead of a static file.
A binary indexed file format should be available for fast access.
me local name, and the command proceeds.
If the host name is not found, or if the remote user is the
super-user, then
.I rshd
checks the file
.I .rhosts
in the login directory found in
.IR /etc/passwd .
If an entry is found for the remote host, or for this
localunix/man/man5/protocols.5                                                                              444     322     145         1542  3621344711  10637                                                                                                                                                                                                                                                                                                                                                                      .TH PROTOCOLS 5  "" CMC
.SH NAME
protocols \- protocol name data base
.SH DESCRIPTION
The
.I protocols
file contains information regarding the known protocols used in the DARPA
Internet.  For each protocol a single line should be present
with the following information:
.HP 10
official protocol name
.br
.ns
.HP 10
protocol number
.br
.ns
.HP 10
aliases
.PP
Items are separated by any number of blanks and/or
tab characters.  A ``#'' indicates the beginning of
a comment; characters up to the end of the line are
not interpreted by routines which search the file.
.PP
Protocol names may contain any printable
character other than a field delimiter, newline,
or comment character.
.SH FILES
/etc/protocols
.SH "SEE ALSO"
getprotoent(3N)
.SH BUGS
A name server should be used instead of a static file.
A binary indexed file format should be available for fast access.
'' notation using the \fIinet_network\fP() routine
from the Internet address manipulation library,
.IR inet (3N).
Network names may contain any printable charunix/man/man5/rhosts.5                                                                                 444     322     145         4637  3621344712  10146                                                                                                                                                                                                                                                                                                                                                                      .TH RHOSTS 5  "" CMC
.SH NAME
rhosts - user-specified file of equivalent hosts and users
.SH DESCRIPTION
This file resides in a user's login directory.
It contains entries, one per line, which are of the form:
.br
	hostname
.br
or
.br
	hostname username
.br
It allows a user to specify a set of users of other systems
which are allowed equivalent capabilities to himself on this system.
.PP
In an environment where a single organization might
have many systems used by a common set of users, it is
often the case that a single user will have login IDs on
many different systems.
In the common case where the login IDs are the same for each user
on all systems, then user authentication is provided by the list
of host names in /etc/hosts.equiv.
In the case where a host is not in /etc/hosts.equiv, or the user
has a different name on another system, the user can provide
individual authentication by adding entries in his personal
.I .rhosts
file.
Users who connect to the system, via
.IR rcp ,
.IR rsh ,
or
.I rlogin
and are authorized via
.IR .rhosts ,
will have privileges on this system exactly equivalent to the
user granting authorization.
.PP
.IR Rshd ,
used to support
.I rsh
and
.I rcp
requests, uses
.I .rhosts
in the following way.
When the connection is made,
.I rshd
gets the ID of the user on the remote ("calling") system.
It then looks up the remote user in the local
.I /etc/passwd
file.
If the remote user is not the super-user, then
.I /etc/hosts.equiv
is checked for the name of the remote host.
If it is found, the user is considered to be
equivalent to the user of the same
local name, and the command proceeds.
If the host name is not found, or if the remote user is the
super-user, then
.I rshd
checks the file
.I .rhosts
in the login directory found in
.IR /etc/passwd .
If an entry is found for the remote host, or this
local user name and remote host combination,
then the user is considered equivalent and the command proceeds.
If this test fails, the command is terminated.
.I Rlogin
uses these files in an analogous fa (   (  shion.
.PP
The \fIhostname\fP entry specified in \fI.rhosts\fP must be the
"primary" host name, i.e. the first one in
.I /etc/hosts .
.SH FILES
$HOME/.rhosts
.SH "SEE ALSO"
rcp(1c), rlogin(1c), rsh(1c), rlogind(8c), rshd(8c),
hosts.equiv(5)
.SH NOTES
On System V systems, users are required to enter their password
(if they have one) on the remote system.
This is due to the operation of
.I login
on these systems.
a single organization might
have many systems used by a common set of users, it is
often the caseunix/man/man5/services.5                                                                               444     322     145         2007  3621344712  10434                                                                                                                                                                                                                                                                                                                                                                      .TH SERVICES 5  "" CMC
.UC 4
.SH NAME
services \- service name data base
.SH DESCRIPTION
The
.I services
file contains information regarding
the known services available in the DARPA Internet.
For each service a single line should be present
with the following information:
.HP 10
official service name
.br
.ns
.HP 10
port number
.br
.ns
.HP 10
protocol name
.br
.ns
.HP 10
aliases
.PP
Items are separated by any number of blanks and/or
tab characters.  The port number and protocol name
are considered a single 
.IR item ;
a ``/'' is used to
separate the port and protocol (e.g. ``512/tcp'').
A ``#'' indicates the beginning of
a comment; characters up to the end of the line are
not interpreted by routines which search the file.
.PP
Service names may contain any printable
character other than a field delimiter, newline,
or comment character.
.SH FILES
/etc/services
.SH "SEE ALSO"
getservent(3N)
.SH BUGS
A name server should be used instead of a static file.
A binary indexed file format should be available for fast access.
rized via
.IR .rhosts ,
will have privileges on this system exactly equivalent to the
user granting authorization.
.PP
.IR Rshd ,
used to support
.I rsh
and
.I rcp
requests, uses
.I .rhosts
in the following way.
When the connection is made,
.I rshd
gets the ID of the user on the remote ("calling") system.
It then looks up the remote user in the local
.I /etc/passwd
file.
If the remote user is not the super-user, then
.I /etc/hosts.equiv
is checked for the name of the remote host.
If it is found, the unix/man/man8/                                                                                         750     322     145            0  3621344717   6444                                                                                                                                                                                                                                                                                                                                                                      unix/man/man8/enpconfig.8                                                                              444     322     145         6015  3621344714  10574                                                                                                                                                                                                                                                                                                                                                                      .TH ENPCONFIG 8 "" CMC
.SH NAME
enpconfig - Process an ENP configuration file 
.SH SYNOPSIS
.B enpconfig
[\fB-d\fR] file
.SH DESCRIPTION
.I File
contains a representation of site-specific
configuration information used by the ENP.
.I Enpconfig
reads this
.I file
and produces
S-records for the corresponding binary information
on standard output.
Redirecting the standard output will create an S-record
file which can be passed to
.I enpload
for loading into the ENP.
.PP
The format of the input
.I file
is a set of lines describing the value of the various configuration
parameters.
The syntax of each line is a leading key word followed by one or more
parameter values.
A pound sign (#) can appear at any point on an input line; the rest of
the line, including the #, is ingored.
Blank lines anywhere in the input are ignored.
The accepted configuration commands are:
.TP
enp ENP_NUM
Required entry.
Specifies the ENP model number.
.TP
host IADDR [EADDR]
Required entry.
Specifies the host's Internet and Ethernet addresses.
If EADDR is omitted, the Ethernet address in the
ENP ID ROM will be used.
.TP
flags NUMBER
This optional entry describes a long word of flag bits.
Meaningful bits are:
.RS 10
.TP
0x01
ENP does the data moving.
Proper use of this flag requires system-specific modifications
to software provided by CMC.
.TP
0x02
ENP and host interpret low order address bit differently.
.TP
0x04
Set MPU read swap bit.
.TP
0x08
Set MPU write swap bit.
.TP
0x10
Do not use ENP console.  Set in normal operation.
.RE
.RS 5
.PP
Flag values 2, 4, and 8 are present to resolve certain
Multibus-related data representation difficulties.
The preferred solution is to procure appropriately
configured ENP-30's.
.RE
.TP
gateway IADDR
Optional entry.
Internet address of primary gateway to use when accessing
hosts not on the local network.
.PP
Parameter values used for these commands are:
.TP
ENP_NUM
One of 10, 20, 2020, 30, 40, or 44.
.TP
IADDR
Network host name, surrounded by quotation marks, e.g.
"cmc-vax", or 
a network number in the standard Internet dot syntax, e.g.
89.0.0.0x79.
Within the network number, each field number can be decimal, octal, or
hex.
The Internet address of a host name is determined by examining /etc/hosts.
.TP
EADDR
Ethernet address of one to twelve hexidecimal digits.
A leading "0x" is optional.
.TP
NUMBER
A number, in any standard base.
.PP
Unless otherwise specified, numbers can be octal (leading "0"), hexidecimal
(leading "0x"), or decimal (other).
.PP
If 
.B -d
is specified,
additional debugging information is printed (also on standard out) by
.IR enpconfig .
This is useful for debugging
.I enpconfig
but is not of general use in the field.
Note that the output file produced under
.B -d
is not suitable for passing to
.IR enpload .
.SH SEE ALSO
ether(4), enpload(8), hosts(5), gethostbyname(3N)
.SH DIAGNOSTICS
Self explanatory.
.SH SAMPLE
# configuration for CMC Cyb system
.br
enp 30
.br
host "cmc-cyb" # use default Ethernet addr
.br
	          # use Internet addr for cmc-cyb in /etc/hosts
.br
flags 0x10     # disallow ENP terminal
d with each protocol family is an address
format.  The following address formats are used by the system:
.sp 1
.nf
._d
#define	AF_UNIX	1	/* local to host (pipes, portals) */
#define	AF_INET	2	/* internetwork: UDP, TCP, etc. */
#define	AF_IMPLINK	3	/* arpanet imp addresses */
#define	AF_PUP	4	/* pup protocols: e.g. BSP */
.fi
.SH SEE ALSO
socket(3N),
ioctl(2),
intro(4)
memory and has stored the new parameters.
.TP
INTPENDING (0x0080)
Interrupt Flag.
When set, indicates that one or more of the founix/man/man8/enpload.8                                                                                444     322     145         4355  3621344714  10253                                                                                                                                                                                                                                                                                                                                                                      .TH ENPLOAD 8 "" CMC
.SH NAME
enpload - download the ENP
.SH SYNOPSIS
.B enpload
[\fB-l\fR|\fB-x\fR] dev
file_1 [file_2 ... file_n]
.SH DESCRIPTION
This program is used to download and execute
one or more files into the ENP to provide
access to the ETHERNET.
.PP
The specified
.I dev
is a name of the form "enp%d", with values of "%d" starting at 0.
.I Enp0
corresponds to the first ENP on the system.
.PP
ENP execution will start at the entry point of the last file specified
.RI ( file_n ).
If
.B \-l
is specified,
.I enpload
will load the ENP but not start execution.
If
.B \-x
is specified,
.I enpload
will start execution in the ENP at the entry point of
.I file_n
without doing a load.
.PP
Files used by
.I enpload
are expected to be in S-record format.
This format consists of strings of printable ASCII characters,
generally followed by a newline.
Within each line, binary values (including the address, data, and checksum)
are represented by two hexidecimal characters per byte.
The structure of each line is:
.TP
Char 1
The letter 'S'
.TP
Char 2
Record type indicator.
Must be one of '0', '1', '2', or '8'.
\'1' and '2' indicate that this is a data record, and the address field
specifies where the data is to be loaded.
\'1' indicates a four digit address field; '2' indicates six digits.
\'8' indicates that the following six digit address field is the entry point for
the file.
\'0' indicates a signon record; the entire record is ignored.
.TP
Chars 3-4
Byte count for this record.
This is the number of data bytes plus the number of bytes in the
address field plus 1 (for the checksum).
Note that these counts are for the number of bytes of binary data, not the
number of digits used for the expanded hex character representation.
.TP
Chars 5 thru 4+n
Address field.  'N' is four if Char 2 is '1', and six if Char 2 is '2' or '8'.
.TP
Chars 4+n+1 thru 4+n+m
Data.  'M' is the number of data bytes.
.TP
Char 4+n+m+1
Checksum.
One's complement of binary summation of preceding bytes in record,
including  bytecount, address, and data bytes.
.PP
All characters after the checksum until the next 'S' are ignored.
.SH FILES
/dev/enpram
.SH SEE ALSO
ether(4), enpconfig(8)
.SH DIAGNOSTICS
Self explanatory.
.SH NOTES
The first character of a file to be downloaded must be 'S'.
hexidecimal digits.
A leading "0x" is optional.
.TP
NUMBER
A number, in any standard base.
.PP
Unless otherwise specified, numbers can be octal (leading "0"), hexidecimal
(leading "0x"), or decimal (other).
.PP
If 
.B -d
is specified,
additional debugging information is prin (   (  unix/man/man8/ftpd.8c                                                                                  444     322     145        10374  3621344715   7750                                                                                                                                                                                                                                                                                                                                                                      .TH FTPD 8C "" CMC
.UC 4
.SH NAME
ftpd \- DARPA Internet File Transfer Protocol server
.SH SYNOPSIS
.B /etc/ftpd
[
.B \-d
] [
.B \-l
] [
.BR \-t timeout
]
.SH DESCRIPTION
.I Ftpd
is the DARPA Internet File Transfer Prototocol
server process.  The server uses the TCP protocol
and listens at the port specified in the ``ftp''
service specification; see
.IR services (5).
.PP
If the 
.B \-d
option is specified,
each socket created will have debugging turned
on (SO_DEBUG).  With debugging enabled, the system
will trace all TCP packets sent and received on a
socket.
.PP
If the
.B \-l
option is specified,
each ftp session is logged on the standard output.
This allows a line of the form 
`/etc/ftpd -l > /tmp/ftplog''
to be used to conveniently maintain a log of ftp sessions.
.PP
The ftp server
will timeout an inactive session after 60 seconds.
If the
.B \-t
option is specified,
the inactivity timeout period will be set to
.IR timeout .
.PP
The ftp server currently supports the following ftp
requests;  case is not distinguished.
.PP
.nf
.ta \w'Request        'u
\fBRequest	Description\fP
ACCT	specify account (ignored)
ALLO	allocate storage (vacuously)
APPE	append to a file
CWD	change working directory
DELE	delete a file
HELP	give help information
LIST	give list files in a directory (``ls -lg'')
MODE	specify data transfer \fImode\fP
NLST	give name list of files in directory (``ls'')
NOOP	do nothing
PASS	specify password
PORT	specify data connection port
QUIT	terminate session
RETR	retrieve a file
STOR	store a file
STRU	specify data transfer \fIstructure\fP
TYPE	specify data transfer \fItype\fP
USER	specify user name
XCUP	change to parent of current working directory
XCWD	change working directory
XPWD	print the current working directory
.fi
.PP
The remaining ftp requests specified in Internet RFC 765 are
recognized, but not implemented.
.PP
.I Ftpd
interprets file names according to the ``globbing''
conventions used by
.IR csh (1).
This allows users to utilize the metacharacters ``*?[]{}~''.
.PP
.I Ftpd
authenticates users according to three rules. 
.IP 1)
The user name must be in the password data base,
.IR /etc/passwd ,
and not have a null password.  In this case a password
must be provided by the client before any file operations
may be performed.
.IP 2)
The user name must not appear in the file
.IR /etc/ftpusers .
.IP 3)
If the user name is ``anonymous'' or ``ftp'', an
anonymous ftp account must be present in the password
file (user ``ftp'').  In this case the user is allowed
to log in by specifying any password (by convention this
is given as the client host's name).
.PP
In the last case, 
.I ftpd
takes special measures to restrict the client's access privileges.
The server performs a 
.IR chroot (2)
command to the home directory of the ``ftp'' user.
In order that system security is not breached, it is recommended
that the ``ftp'' subtree be constructed with care;  the following
rules are recommended.
.IP ~ftp)
Make the home directory owned by ``ftp'' and unwritable by anyone.
.IP ~ftp/bin)
Make this directory owned by the super-user and unwritable by
anyone.  The program
.IR ls (1)
must be present to support the list commands.  This
program should have mode 111.
.IP ~ftp/etc)
Make this directory owned by the super-user and unwritable by
anyone.  The files
.IR passwd (5)
and
.IR group (5)
must be present for the 
.I ls
command to work properly.  These files should be mode 444.
.IP ~ftp/pub)
Make this directory mode 777 and owned by ``ftp''.  Users
should then place files which are to be accessible via the
anonymous account in this directory.
.IP ~ftp/dev
Make this directory owned by the super-user and unwritable by anyone.
.IP ~ftp/dev/socket
Make this directory owned by the super-user and unwritable by anyone.
There should be links here to the special files /dev/socket/s*,
so the socket routines will work properly.
.SH "SEE ALSO"
ftp(1C)
.SH BUGS
There is no support for aborting commands.
.PP
The anonymous account is inherently dangerous and should
avoided when possible.
.PP
The server must run as the super-user
to create sockets with privileged port numbers.  It maintains
an effective user id of the logged in user, reverting to
the super-user only when binding addresses to sockets.  The
possible security holes have been extensively
scrutinized, but are possibly incomplete.
TP
STARTED (0x0002)
Enables the LANCE to send and receive packets, perform
direct memory access, and do buffer management.
.TP
INITIALIZE (0x0001)
Causes the LANCE to begin the initialization procedure and 
access the initialization block.
.RE
.TP
EIOCGETBUF
Runix/man/man8/rlogind.8c                                                                               444     322     145         5335  3621344715  10432                                                                                                                                                                                                                                                                                                                                                                      .TH RLOGIND 8C "" "CMC 2.0"
.UC 4
.SH NAME
rlogind \- remote login server
.SH SYNOPSIS
.B /etc/rlogind
[
.B \-d
]
.SH DESCRIPTION
.I Rlogind
is the server for the 
.IR rlogin (1C)
program.  The server provides a remote login facility
with authentication based on privileged port numbers.
.PP
.I Rlogind
listens for service requests at the port indicated in
the ``login'' service specification; see
.IR services (5).
When a service request is received the following protocol
is initiated:
.IP 1)
The server checks the client's source port.
If the port is not in the range 0-1023, the server
aborts the connection.
.IP 2)
The server checks the client's source address.
If the address is associated with a host for which no
corresponding entry exists in the host name data base (see
.IR hosts (5)),
the server aborts the connection.
.PP
Once the source port and address have been checked, 
.I rlogind
allocates a pseudo terminal (see 
.IR pty (4)),
and manipulates file descriptors so that the slave
half of the pseudo terminal becomes the 
.BR stdin ,
.BR stdout ,
and
.B stderr 
for a login process.
The login process is an instance of the
.IR login (1)
program.
The login process then proceeds with the authentication
process as described in
.IR rshd (8C),
but if automatic authentication fails, it reprompts the user
to login as one finds on a standard terminal line.
.PP
The parent of the login process manipulates the master side of
the pseduo terminal, operating as an intermediary
between the login process and the client instance of the
.I rlogin
program.  In normal operation, the packet protocol described
in
.IR pty (4)
is invoked to provide ^S/^Q type facilities and propagate
interrupt signals to the remote programs.  The login process
propagates the client terminal's baud rate and terminal type,
as found in the environment variable, ``TERM''; see
.IR environ (7).
.SH DIAGNOSTICS
All diagnostic messages are returned on the connection
associated with the
.BR stderr ,
after which any network connections are closed.
An error is indicated by a leading byte with a value of 1.
.PP
.B ``Hostname for your address unknown.''
.br
No entry in the host name database existed for
the client's machine.
.PP
.B ``Try again.''
.br
A
.I fork
by the server failed.
.PP
.B ``/bin/sh: ...''
.br
The user's login shell could not be started.
.SH BUGS
The authentication procedure used here assumes the integrity
of each client machine and the connecting medium.  This is
insecure, but is useful in an ``open'' environment.
.PP
A facility to allow all data exchanges to be encrypted should be
present.
.SH CAVEAT
.I Rlogin
and
.I rlogind
are available on CMC TCP Releases 2.0 and later.
.I Telnet
and
.I telnetd
are available on all releases for interactive access to remote systems.
ftp'' user.
In order that system security is not breached, it is recommended
that the ``ftp'' subtree be constructed with care;  the following
rules are recommended.
.IP ~ftp)
Make the home directory owned by ``ftp'' and unwritable by anyone.
.IP ~ftp/bin)
Make this directory owned by the sunix/man/man8/rshd.8c                                                                                  444     322     145        10454  3621344716   7753                                                                                                                                                                                                                                                                                                                                                                      .TH RSHD 8C "" CMC
.UC 4
.SH NAME
rshd \- remote shell server
.SH SYNOPSIS
.B /etc/rshd
.SH DESCRIPTION
.I Rshd
is the server for the 
.IR rcmd (3X)
routine and, consequently, for the
.IR rsh (1C)
program.  The server provides remote execution facilities
with authentication based on privileged port numbers.
.PP
.I Rshd
listens for service requests at the port indicated in
the ``cmd'' service specification; see
.IR services (5).
When a service request is received the following protocol
is initiated:
.IP 1)
The server checks the client's source port.
If the port is not in the range 0-1023, the server
aborts the connection.
.IP 2)
The server reads characters from the socket up
to a null (`\e0') byte.  The resultant string is
interpreted as an ASCII number, base 10.
.IP 3)
If the number received in step 2 is non-zero,
it is interpreted as the port number of a secondary
stream to be used for the 
.BR stderr .
A second connection is then created to the specified
port on the client's machine.  The source port of thi (   (  s
second connection is also in the range 0-1023.
.IP 4)
The server checks the client's source address.
If the address is associated with a host for which no
corresponding entry exists in the host name data base (see
.IR hosts (5)),
the server aborts the connection.
.IP 5)
A null terminated user name of at most 16 characters
is retrieved on the initial socket.  This user name
is interpreted as a user identity to use on the
.BR server 's
machine.
.IP 6)
A null terminated user name of at most 16 characters
is retrieved on the initial socket.  This user name
is interpreted as the user identity on the
.BR client 's
machine.
.IP 7)
A null terminated command to be passed to a
shell is retrieved on the initial socket.  The length of
the command is limited by the upper bound on the size of
the system's argument list.  
.IP 8)
.I Rshd
then validates the user according to the following steps.
The remote user name is looked up in the password file
and a
.I chdir
is performed to the user's home directory.  If either
the lookup or 
.I chdir
fail, the connection is terminated.
If the user is not the super-user, (user ID 0), the file 
.I /etc/hosts.equiv
is consulted for a list of hosts considered ``equivalent''.
If the client's host name is present in this file, the
authentication is considered successful.  If the lookup
fails, or the user is the super-user, then the file
.I .rhosts
in the home directory of the remote user is checked for
the machine name and identity of the user on the client's
machine.  If this lookup fails, the connection is terminated.
.IP 9)
A null byte is returned on the connection associated
with the
.B stderr 
and the command line is passed to the normal login
shell of the user.  The
shell inherits the network connections established
by
.IR rshd .
.SH DIAGNOSTICS
All diagnostic messages are returned on the connection
associated with the
.BR stderr ,
after which any network connections are closed.
An error is indicated by a leading byte with a value of
1 (0 is returned in step 9 above upon successful completion
of all the steps prior to the command execution).
.PP
.B ``locuser too long''
.br
The name of the user on the client's machine is
longer than 16 characters.
.PP
.B ``remuser too long''
.br
The name of the user on the remote machine is
longer than 16 characters.
.PP
.B ``command too long''
.br
The command line passed exceeds the size of the argument
list (as configured into the system).
.PP
.B ``Hostname for your address unknown.''
.br
No entry in the host name database existed for
the client's machine.
.PP
.B ``Login incorrect.''
.br
No password file entry for the user name existed.
.PP
.B ``No remote directory.''
.br
The 
.I chdir
command to the home directory failed.
.PP
.B ``Permission denied.''
.br
The authentication procedure described above failed.
.PP
.B ``Can't make pipe.''
.br
The pipe needed for the 
.BR stderr ,
wasn't created.
.PP
.B ``Try again.''
.br
A
.I fork
by the server failed.
.PP
.B ``/bin/sh: ...''
.br
The user's login shell could not be started.
.SH FILES
/etc/hosts.equiv
.br
$HOME/.rhosts
.SH SEE ALSO
rsh(1C),
rcmd(3X)
.SH BUGS
The authentication procedure used here assumes the integrity
of each client machine and the connecting medium.  This is
insecure, but is useful in an ``open'' environment.
.PP
A facility to allow all data exchanges to be encrypted should be
present.

command to work properly.  These files should be mode 444.
.IP ~ftp/pub)
Make this directory mode 777 and owned by ``ftp''.  Users
should then place files which are to be accessible via the
anonymous account in unix/man/man8/telnetd.8c                                                                               444     322     145         3276  3621344717  10437                                                                                                                                                                                                                                                                                                                                                                      .TH TELNETD 8C "" CMC
.UC 4
.SH NAME
telnetd \- DARPA TELNET protocol server
.SH SYNOPSIS
.B /etc/telnetd
[
.B \-d
] [
.I port
]
.SH DESCRIPTION
.I Telnetd
is a server which supports the DARPA standard TELNET
virtual terminal protocol.  The TELNET server operates
at the port indicated in the ``telnet'' service description;
see
.IR services (5).
This port number may be overridden (for debugging purposes)
by specifying a port number on the command line.  If the
.B \-d
option is specified, each socket created by
.I telnetd
will have debugging enabled (see SO_DEBUG in
.IR socket (3N)).
.PP
.I Telnetd
operates by allocating a pseudo-terminal device (see
.IR pty (4))
for a client, then creating a login process which has
the slave side of the pseudo-terminal as 
.BR stdin ,
.BR stdout ,
and
.BR stderr .
.I Telnetd
manipulates the master side of the pseudo terminal,
implementing the TELNET protocol and passing characters
between the client and login process.
.PP
When a TELNET session is started up, 
.I telnetd
sends a TELNET option to the client side indicating
a willingness to do ``remote echo'' of characters.
The pseudo terminal allocated to the client is configured
to operate in ``cooked'' mode, and with XTABS and CRMOD
enabled (see
.IR tty (4)).
Aside from this initial setup, the only mode changes
.I telnetd
will carry out are those required for echoing characters
at the client side of the connection.
.PP
.I Telnetd
supports binary mode, and most of the common TELNET options,
but does not, for instance, support timing marks.  Consult
the source code for an exact list of which options are not
implemented.
.SH "SEE ALSO"
telnet(1C)
.SH BUGS
A complete list of the options supported should be given here.
l inherits the network connections established
by
.IR rshd .
.SH DIAGNOSTICS
All diagnostic messages are returned on the connection
associated with the
.BR stderr ,
after which any network connections are closed.
An error is indicated by a leading byte with a value of
1 (0 is returned in step 9 above upon successful compunix/man/man8/tftpd.8c                                                                                 444     322     145         2561  3621344717  10115                                                                                                                                                                                                                                                                                                                                                                      .TH TFTPD 8C "" CMC
.UC 4
.SH NAME
tftpd \- DARPA Trivial File Transfer Protocol server
.SH SYNOPSIS
.B /etc/tftpd
[
.B \-d
] [
.I port
]
.SH DESCRIPTION
.I Tftpd
is a server which supports the DARPA Trivial File Transfer
Protocol.  The TFTP server operates
at the port indicated in the ``tftp'' service description;
see
.IR services (5).
This port number may be overridden (for debugging purposes)
by specifying a port number on the command line.  If the
.B \-d
option is specified, each socket created by
.I tftpd
will have debugging enabled (see SO_DEBUG in
.IR socket (3N)).
.PP
The use of
.I tftp
does not require an account or password on the remote system.
Due to the lack of authentication information, 
.I tftpd
will allow only publicly readable files to be
accessed.
Note that this extends the concept of ``public'' to include
all users on all hosts that can be reached through the network;
this may not be appropriate on all systems, and its implications
should be considered before enabling tftp service.
.SH "SEE ALSO"
tftp(1C)
.SH BUGS
This server is known only to be self consistent
(i.e. it operates with the user TFTP program,
.IR tftp (1C)).
Due to the unreliability of the transport protocol
(UDP) and the scarcity of TFTP implementations,
it is uncertain whether it really works.
.PP
The search permissions of the directories leading to the files accessed
are not checked.
ent side of the connection.
.PP
.I Telnetd
supports binary mode, and most of the common TELNET options,
but does not, for instance, support timunix/man/prman                                                                                         555     322     145          160  3621344720   6703                                                                                                                                                                                                                                                                                                                                                                      
# leave the above blank line - for sh.

for i in $* ; do
    d=`/usr/lib/manprog $i`
    nroff -man $d $i
done
pd
[
.B \-d
] [
.I port
]
.SH DESCRIPTION
.I Tftpd
is a server which supports the DARPA Trivial File Transfer
Protocol.  The TFTP server operates
at the port indicated in the ``tftp'' service description;
see
.IR services (5).
This port number may be overridden (for debugging purposes)
by specifying a port number on the command line.  If the
.B \-d
option is specified, each socket created by
.I tfunix/sys/                                                                                              750     322     145            0  4104156744   5642                                                                                                                                                                                                                                                                                                                                                                      unix/sys/examples/                                                                                     750     322     145            0  3621344304   7452                                                                                                                                                                                                                                                                                                                                                                       (   (  unix/sys/examples/README                                                                               440     322     145        12077  3621344301  10442                                                                                                                                                                                                                                                                                                                                                                      	In order to use the ENP, you must include several new device
drivers in your system.  The details of how to do this vary widely from
site to site.  While no attempt has been made to include complete
directions for any system, this directory contains sample files and a
few hints for making new systems on some of our development machines.

	NOTE:  IT IS ASSUMED THAT THE PERSON DOING THE INSTALLATION HAS
SUFFICIENT EXPERTISE TO BE ABLE TO ADD DEVICE DRIVERS TO THE SYSTEM.  IF
THAT PERSON IS YOU, AND YOU'RE NOT FAMILIAR WITH THE PROCEDURES ON YOUR
SYSTEM, CONTACT SOMEONE WHO IS.  DO NOT TRY TO BLINDLY FOLLOW ANTHING
DESCRIBED IN THIS SECTION, AS IT IS MAY WELL HAVE NASTY CONSEQUENCES
ON YOUR SYSTEM.

	There are many approaches taken on how to structure system
configurations.  Many systems keep these tools in a directory such as
/usr/src/...something..., for example /usr/src/config or
/usr/src/uts/nm68k.  You might poke around there looking for where your
system configuration tools are.  Some systems put the object files for
device drivers into a combined library, then reference it during the ld.
Others keep device drivers in separate modules which are passed directly
to ld.  The following examples show a few of the different ways it's done.

CYB and other systems based on SUN's MPU

	On this system, a new unix is made by running a complex shell
script which sets up the environment and then runs a Makefile.  Sample
files for these systems are:

conf.c
	Fragment of the file which defines device drivers to the system.

config.c
	A fragment of code intended to indicate the type of machination
	necessary to include the ENP in your system.  The ENP occupies
	128k of memory space on the host bus (Multibus, VME, etc.). The
	Unix system (aside from this device driver) must remain unaware of
	this memory.
	This code is what was added to a UniPlus+ Sys V port to a 
	SUN-type 68000 system.  It steals 128K from the kernel virtual
	address space, and sets it to address the Multibus physical
	address of the ENP.

config.h
	The relevant fragment of config.h from our development system.
	This just shows how we set the physical and kernel virtual
	addresses for an ENP-30 on a Multibus system.

	Changes similar to these examples should be included in your
config.c and conf.c files, which must be compiled and made available for
loading the system.  Further steps for building the new system on the Cyb
include:

    Modify the shell script to know about the new ENP type of device.  On
	our system this is the file /usr/src/config/MAKEUNIX.

    Compile the new device drivers.  Combine all the .o files into one
	loadable file, as by "ld -r *.o" in the sys directory.  Move the
	resulting file into the directory where the system will be made.

    Load the new unix system.  On our system this is done from directory
	/usr/src/config by the command:
		MAKEUNIX unix4_cek

Motorola VME-10:
	This system uses the utility "config" and the descriptive files
"master" and "dfile" to maintain the system description.  Sample files
from this system are:

dfile.sample
master.sample
	The relevant fragments of our system master and dfile files
	used to configure the device drivers into our system.
	When installed on your system, the major device numbers in
	master must match the corresponding devices made by mkdev.sh.
	The correspondance is:
		so_	/dev/socket/s*
		pts	/dev/ttyp*
		ptc	/dev/ptyp*
		enpr	/dev/enpram
	(The first entry in master.sample, enp, is to cause ENP 
	interrupts to be properly handled and does not correspond
	to a /dev entry.)

mkdev.sh
	Sample shell script used to create new devices.  This is an
	example only; at a minimum you should check the major device
	numbers before running mkdev.sh on your system.

	Changes similar to these samples should be added to your master
and dfiles.  A new system is then made with this new configuration, and
including the new device drivers.  On our development system, the steps
to do this are as follows.

    Compile the drivers and support code.  A sample command line to do
	this is:
		M68000= cc -c -O -W0,-XT -DENP=10 *.c

    Put the resulting object modules in the library that is referenced
	when building unix.  On our system this is /usr/src/uts/nm68k/lib2.

    Update your system "master" and "dfile" files to include the
	information about the ENP drivers, similar to master.sample
	and dfile.sample.

    Run "config", using this master and dfile, to produce new low.s,
	m68kvec.s, and conf.c files.  On our system these are kept in the
	directory /usr/src/uts/nm68k/cf.

    Compile these files.  On our system this is done with the command:
	cc -c -O -T -DVME10 -DM68451 -DM68010 conf.c low.s m68kvec.s

    Load the new unix system.  On our system this is done from directory
	/usr/src/uts/nm68k/cf by:
		mv -f ../unix ../unix.bak
		/bin/ld -o ../unix \
				ld.file \
				m68kvec.o \
				../lib2 \
				low.o \
				../locore.o \
				conf.o \
				linesw.o \
				../lib[0-9] \
				name.o \
				-lc

	This sample assumes that you use the config utility for configuring
your Unix system.  It is possible of course to modify the low.s, m68kvec.s,
and conf.c files directly if you want to.
s them to 0.
.RE
.PP
.I Setsockopt
calls are expressed:
.br
	setsockopt (s, SOL_ETHER, command, &arg, sizeof (arg))

The
.I setsockopt
commands are:
.TP
EIOCSETMODE
Allows the user to set the LANCE mode register.
.I Arg
is
.B short int.
Settable bits are:
.RS 5
.TP
PROMISCUOUS (0x8000)
Indicates that the ENP will receive all messages on the media.
Note that the socket from
which this command is issued will still only receive
datagrams with a typunix/sys/examples/conf.c                                                                               444     322     145         2527  3621344302  10637                                                                                                                                                                                                                                                                                                                                                                      /* for now we always have ptys */
#define PTYS
#ifdef PTYS
extern int ptsopen(),   ptsclose(),   ptsread(),    ptswrite();
extern int ptcopen(),   ptcclose(),   ptcread(),    ptcwrite();
extern int ptsioctl(),  ptcioctl();
extern struct tty pt_tty[];
#endif PTYS


#ifdef ENP		/* Has CMC Ethernet Node Processor */
extern int so_open(), so_close(), so_read(), so_write(), so_ioctl();
extern int enpropen(), enprclose(), enprread(), enprwrite(), enprspcl();
#endif ENP

/**
 ** character device switch table
 **/

struct cdevsw cdevsw[] = {
	.
	.
	.
#ifdef PTYS
    ptcopen,   ptcclose, ptcread,   ptcwrite,    ptcioctl,  0,	    /* ptc 20 */
    ptsopen,   ptsclose, ptsread,   ptswrite,    ptsioctl,  pt_tty, /* pts 21 */
#else
    nodev,     nodev,    nodev,     nodev,       nodev,     0,
    nodev,     nodev,    nodev,     nodev,       nodev,     0,
#endif
#ifdef ENP
  so_open,  so_close,  so_read,  so_write,    so_ioctl,     0,	    /* 22 */
  enpropen, enprclose, enprread, enprwrite,   enprspcl,     0,	    /* 23 */
#else
    nodev,     nodev,    nodev,     nodev,       nodev,     0,
    nodev,     nodev,    nodev,     nodev,       nodev,     0,
#endif
    0,
};

/**
 ** tty structures, tty ptr structures, tty high & low watermarks
 **/

#ifdef PTYS
#define PTC_DEV 20
int ptc_dev = PTC_DEV;
#endif PTYS

l5intr(dev)
{
#ifdef ENP
	enpintr();
#endif ENP
}
ipt which sets up the environment and then runs a Makefile.  Sample
files for these systems are:

conf.c
	Fragment of the file which defines device drivers to the systemunix/sys/examples/config.c                                                                             444     322     145         2171  3621344302  11152                                                                                                                                                                                                                                                                                                                                                                      /*
 *	NOTE!	This is NOT a complete version of oem7init --
 *		is is ONLY the portion relevant to mapping an
 *		ENP into kernel virtual address space.
 */

#include "config.h"

# ifdef ENP
#	define ENPSEGS 4
#	define ENPEND  (ENP_VADDR + 128 * 1024)
# endif ENP

oem7init()
{
	/*
	 * Free the context page map.
	 *
	 * There are a total of 64 segments supported by the MMU.
	 * A total of NSYSSEG segments are used for the kernel.
	 * Segment 0 through NSYSSEG-1 and segment 63 are used
	 * by the kernel.
	 *
	 * To use more segments decrease the 2nd parameter below
	 * and set up the pages in sysinit() associated with
	 * that context. All of the virtual segments
	 * are mapped 1 to 1 by the kernel startup code.
	 * UEND in /usr/include/sys/param.h must also be decreased
	 * by SEGINCR for each segment.
	 */


# ifdef ENP
	mfree(cxmap, 64-nsysseg-1-PROFSEGS-ENPSEGS, nsysseg);
	enpinit();
# else
	mfree(cxmap, 64-nsysseg-1-PROFSEGS, nsysseg);
# endif ENP
}

# ifdef ENP
static
enpinit()
{
	register int v, p;

	p = ENP_PADDR >> PAGESHIFT;
	for (v = ENP_VADDR; v < ENPEND; v += PAGEINCR) {
		*vtopage(v) = ASMBRAM | p++;
	}
}
# endif ENP
ev,     0,
#endif
    0,
};

/**
 ** tty structures, tty ptr structures, tty high & low watermarks
 **/

#ifdef PTYS
#define PTC_DEV 20
int ptc_dev = PTC_DEV;
#endif PTYS

l5intr(dev)
{
#ifdef ENP
	enpintr();
#endif ENP
}
ipt which sets up the environment and then runs a Makefile.  Sample
files for these systems are:

conf.c
	Fragment of the file which defines device drivers to the system (   (  unix/sys/examples/config.h                                                                             444     322     145          343  3621344303  11137                                                                                                                                                                                                                                                                                                                                                                      
/* Define locations for CMC ENP-30 (128K private multibus ram) */
/* This is fixed at segments 59-62, inclusive */
# define ENP_VADDR 0x1D8000			/* kernel virtual addr */
# define ENP_PADDR 0xC0000			/* Multibus phys addr */

NP_VADDR + 128 * 1024)
# endif ENP

oem7init()
{
	/*
	 * Free the context page map.
	 *
	 * There are a total of 64 segments supported by the MMU.
	 * A total of NSYSSEG segments are used for the kernel.
	 * Segment 0 through NSYSSEG-1 and segment 63 are used
	 * by the kernel.
	 *
	 unix/sys/examples/dfile.sample                                                                         444     322     145          547  3621344303  12015                                                                                                                                                                                                                                                                                                                                                                      * Sample changes for dfile to support CMC ENP networking
*
* Part 1
*
* CMC network devices - added 28 January 1984
*
* dev	vector	addr	bus	count
*
cmc	304	0	4
net0	0	0	0	20
enp	0	0	0	10
ptc	0	0	0	10
pts	0	0	0	10
*
* Part 3
*
* m68k Specific Parameters
*
ram	5	000000	180000	60000	* system ram: no parity
ram	4	180000	7e0000	10000	* VME BUS: parity, 64k bds 
ed by the MMU.
	 * A total of NSYSSEG segments are used for the kernel.
	 * Segment 0 through NSYSSEG-1 and segment 63 are used
	 * by the kernel.
	 *
	 unix/sys/examples/master.sample                                                                        444     322     145          377  3621344304  12227                                                                                                                                                                                                                                                                                                                                                                      * Part 1 changes to master file to support CMC ENP networking
*
* CMC network devices - added 28 January 1985
*
cmc	4	0	102	enp	0	0	0	1	5
net0	0	37	104	so_	0	0	9	64	5
enp	0	37	144	enp_	0	0	10	64	5
pts	0	37	144	pts	0	0	11	64	5
ptc	0	37	144	ptc	0	0	12	64	5
ram	5	000000	180000	60000	* system ram: no parity
ram	4	180000	7e0000	10000	* VME BUS: parity, 64k bds 
ed by the MMU.
	 * A total of NSYSSEG segments are used for the kernel.
	 * Segment 0 through NSYSSEG-1 and segment 63 are used
	 * by the kernel.
	 *
	 unix/sys/examples/mkdev.sh                                                                             444     322     145         2014  3621344304  11201                                                                                                                                                                                                                                                                                                                                                                      
: This is the shell file we used to create the network devices on our
: system.  It is included as an example of how you might create the
: devices on your system.  We do not recommend that you run it directly.
: In particular, the major device numbers need to be set correctly for
: your system.

mkdir /dev/socket
mknod /dev/socket/s1 c 9 1
mknod /dev/socket/s2 c 9 2
mknod /dev/socket/s3 c 9 3
mknod /dev/socket/s4 c 9 4
mknod /dev/socket/s5 c 9 5
mknod /dev/socket/s6 c 9 6
mknod /dev/socket/s7 c 9 7
mknod /dev/socket/s8 c 9 8
mknod /dev/socket/s9 c 9 9
mknod /dev/socket/s10 c 9 10
mknod /dev/socket/s11 c 9 11
mknod /dev/socket/s12 c 9 12
mknod /dev/socket/s13 c 9 13
mknod /dev/socket/s14 c 9 14
mknod /dev/socket/s15 c 9 15
mknod /dev/socket/s16 c 9 16
mknod /dev/socket/s17 c 9 17
chmod +rw /dev/socket/*

mknod /dev/ttyp0 c 11 0
mknod /dev/ttyp1 c 11 1
mknod /dev/ttyp2 c 11 2
mknod /dev/ttyp3 c 11 3

mknod /dev/ptyp0 c 12 0
mknod /dev/ptyp1 c 12 1
mknod /dev/ptyp2 c 12 2
mknod /dev/ptyp3 c 12 3

mknod /dev/enpram c 10 0
PAGESHIFT;
	for (v = ENP_VADDR; v < ENPEND; v += PAGEINCR) {
		*vtopage(v) = ASMBRAM | p++;
	}
}
# endif ENP
ev,     0,
#endif
    0,
};

/**
 ** tty structures, tty ptr structures, tty high & low watermarks
 **/

#ifdef PTYS
#define PTC_DEV 20
int ptc_dev = PTC_DEV;
#endif PTYS

l5intr(dev)
{
#ifdef ENP
	enpintr();
#endif ENP
}
ipt which sets up the environment and then runs a Makefile.  Sample
files for these systems are:

conf.c
	Fragment of the file which defines device drivers to the systemunix/sys/if_tcp.c                                                                                      444     322     145         4154  3725101013   7331                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

#include <CMC/types.h>
#include <CMC/errno.h>
#include <CMC/ring.h>
#include <CMC/netbfr.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/in.h>
#include <CMC/enp.h>

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>


/*
 *		if_tcp.c
 *
 *	TCP specific routines - Called through protocol switch inetsw[].
 *
 *	tcpbind()
 *	tcpconnect()
 *	tcpclose()
 *	tcpsend()
 *	tcprecv()
 */


extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;
extern HOST	MYHOSTPARAM;

static
sockaddr_in	sin = {AF_INET};


tcpbind(s)
register SOCKET	*s;
{
	return (0);
}


tcpconnect(s, to, type, flags)
register SOCKET		*s;
register sockaddr_in	*to;
{
	register BFR	*bp;
	register OPN	*op;

	extern		wait_for();

	if ((to) && ((to->sin_port == 0) || (to->sin_addr.s_addr == 0))) {
		u.u_error = EINVAL;	/* ? */
		return;
	}

	bp = (BFR *) get_buf(0);
	bp->b_device = s->so_proto->pr_channel;

	op = (OPN *) bp->b_addr;
	enp_move(s->so_name, op->o_name, SOCKNAMESIZE);
	op->o_id = htonl(s->so_enpid);
	op->o_status = -1;
	op->o_type = htons(type);

	if (to)
		enp_move(to, op->o_parm, SOCKNAMESIZE);
	else
		enp_zero(op->o_parm, SOCKNAMESIZE);

	s->so_o_bfr = bp;		/* Save open buffer and		*/
	s->so_o_opn = op;		/* address of open parm in bfr	*/
	s->so_state |= SS_CONNECTING;

	to_enp(enp->h_open, bp);

	if (type != SS_LISTEN)
		u.u_error = wait_for(s, flags);
}


tcpclose(s)
register SOCKET	*s;
{
	register BFR	*bp;
	register int	x;

	if ( s->so_o_bfr ) {
		fre_buf( s->so_o_bfr );
		s->so_o_bfr = 0;
	}

	bp = (BFR *) get_buf(0);
	bp->b_device = s->so_enpid;
	bp->b_flags = (SC_CLOSE | SC_CTL);
	bp->b_resv = 0;

	to_enp(enp->h_tonet, bp);

	if (s->so_options & SO_LINGER) {
		x = splnet();
		while (bp->b_resv == 0)
			sleep(bp, PENP);
		splx(x);
		fre_buf(bp);
	}
}


tcpsend(s)
register SOCKET	*s;
{
	return (0);
}


tcprecv(s)
register SOCKET	*s;
{
	return (0);
}
virtual
	addresses for an ENP-30 on a Multibus system.

	Changes similar to these examples should be included in your
config.c and conf.c files, which must be compiled and made available for
loading the system.  Further steps for building the new system on the Cyb
include:

    Modify the shell script to know about the new ENP type of device.  On
	our system this is the file /usr/src/config/MAKEUNIX.
unix/sys/enp10.c                                                                                       444     322     145         5416  3621344300   7015                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation 
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

/*
 *	File:	 enp10.c	Module(s): HOST Resident
 *	ENP:	 10/VMEbus
 *	Unix:	 System V
 *
 *	This file implements the support procedures utilized by
 *	sock_driver.c which may change on a per-system basis.
 *	In particular, details of moving data between the user
 *	address space and the kernel and/or ENP are handled here;
 *	also included are those routine which may vary for different
 *	models of ENP.
 */

#include <sys/param.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/inode.h>
#include <sys/file.h>
#include <CMC/errno.h>
#include <CMC/signal.h>
#include "enp_addr.h"
#include <CMC/netbfr.h>
#include <CMC/ring.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include "copyin.h"


/*
 *	Usefull constants
 */

# define K *1024


/*
 *	Fundamental attributes of the implementation
 */

# define INTENP 0xE01			/* Poke to interrupt ENP */
# define ENPVAL 0xFF			/* Value to poke */

# define ENPINTBASE (ENPBASE + 124 K)
# define ENPINT (caddr_t)(ENPINTBASE + INTENP)		/* Intr. addr */

# define ENPGOADDR	0x1000				/* Start addr */
# define GOCMD		0x8080				/* Start command */

# define ENPRSADDR	((124 K) + 1)			/* Reset addr */
# define RSCMD		0x01				/* Reset command */

struct startup {
	short	g_cmd;
	short	 (   (  g_dummy;
	long	g_addr;
};

/*
 *	ENP model dependent routines
 *
 *	intenp()		Interrupt the ENP
 *	enpintr()		ENP interrupt handler
 */

intenp()
{
	*ENPINT = ENPVAL;
}

enpintr()
{
	enpservice();
}

enpgo(enpaddr, arg)
{
	struct startup *enpgo;

	enpgo = (struct startup *) (enpaddr + ENPGOADDR);
	enpgo -> g_addr = arg;
	enpgo -> g_cmd = GOCMD;
}

resetenp(enpaddr)
{
	/*
	 * Rev A & B ENP-10's can't be reset.
	 * Reseting a Rev C, or later, ENP-10 will kill the Unix system.
	 * ---> ignore reset requests
	 */
}


/*
 *	Unix dependent routines
 *
 *	kern_to_user()		Move data from kernel to user space
 *	user_to_kern()		Move data from user to kernel space
 *	splnet()		Set processor level for ENP
 *	device()		Convert user fid to major,minor
 */

user_to_kern(from, to , count)
{
	if (count > 0) {
		if (copyin (from, to, count)) {
			u.u_error = EFAULT;
			return (EFAULT);
		}
	}
	return (0);
}

kern_to_user(from, to, count)
{
	if (count > 0) {
		if (copyout (from, to , count)) {
			u.u_error = EFAULT;
			return (EFAULT);
		}
	}
	return (0);
}

splnet()
{
	return (spl5());
}

device(fid)
{
	register struct file *fp;

	fp = (struct file *) getf (fid);	/* convert fid to file * */
	if (fp == 0)				/* failed, so fid is bogus */
		return (-1);

	return ((int) fp->f_inode->i_rdev);
}
ntr. addr */

# define ENPGOADDR	0x1000				/* Start addr */
# define GOCMD		0x8080				/* Start command */

# define ENPRSADDR	((124 K) + 1)			/* Reset addr */
# define RSCMD		0x01				/* Reset command */

struct startup {
	short	g_cmd;
	short	unix/sys/README                                                                                        444     322     145         4475  3621344305   6617                                                                                                                                                                                                                                                                                                                                                                      	These files comprise the Unix System V kernel changes required
to support an ENP providing TCP/IP and Raw Ethernet services.

examples
	A directory containing example Unix configuration code fragments,
Makefiles, etc.

copyin.h
	On some systems (including one of our development systems), the
	standard routines copyin and copyout are not provided.  This
	file defines macros to call the appropriate routines in lieu of
	copyin and copyout.  The defines in copyin.h should be set
	appropriately for your system (or removed if you have copyin/
	copyout.)

enp_addr.h
	ENP address definitions.

pty.c
	A true System V pseudo-teletype driver.  This guy is functionally
	compatible (and interoperable) with the 4.2BSD pty driver.  It
	is NOT ioctl compatible with ports of that driver to Sys V;
	you MUST <CMC/pty.h> to utilize this driver.

	You need to create two sets of pseudo-teletype special files.
	/dev/ptyp[0-9a-f] correspond to the "master" half of the pseudo-
	teletypes, which have driver routines named ptc*.  The slave
	half (pts*) corresponds to special files named /dev/ttyp[0-9a-f].

enpNN.c
enp.c
sock_driver.c
	These three files comprise the ENP driver.  EnpNN.c contains
	code whice is specific to the ENP and/or to Unix Sys V. The
	enp.c file implements the generic portions of the interface.
	Sock_driver.c is insensitive to such things, and does the
	bulk of the work.

	The special files handled by sock_driver are named
	/dev/socket/s[1-255].  The minor device number of each special
	file should be the same as the numerical portion of its name;
	i.e., /dev/socket/s3 should have minor device number 3.
	Do not use minor device 0. For a system with relatively light
	network usage, we suggest creating at least s1-s17; a heavily
	networked system may need s1-s33.

enpram.c
	This is a device driver analogous to /dev/mem which allows
	access to the RAM of the ENP.  The associated special file
	is called /dev/enpram. This device is used by the the CMC ENP
	downloader program enpload.c.

eth_proto.c
if_eth.c
	These two files define the Ethernet "domain" and implement the
	Raw Ethernet specific routines used by sock_driver.c.

in_proto.c
if_tcp.c
if_rip.c
if_udp.c
	These four files define the Internet "domain" and implement the
	TCP/IP, Raw Internet Datagram service, and User Datagram Protocol
	specific routines used by sock_driver.c.
.  Further steps for building the new system on the Cyb
include:

    Modify the shell script to know about the new ENP type of device.  On
	our system this is the file /usr/src/config/MAKEUNIX.
unix/sys/copyin.h                                                                                      444     322     145          722  3621344306   7361                                                                                                                                                                                                                                                                                                                                                                      /*
 * This file contains macros which map the standard "copyin" and "copyout"
 * system routines into the "mmuread" and "mmuwrite" routines used on early
 * versions of the VME software.
 *
 * If your system already has copyin and copyout, you should remove these
 * defines.
 */

#ifdef VME27			/* only system known to have this problem */
#define copyin(from,to,lth)	mmuread ((from), (to), (lth))
#define copyout(from,to,lth)	mmuwrite ((to), (from), (lth))
#endif
 should be set
	appropriately for your system unix/sys/enp.c                                                                                         644     322     145        17400  3621344307   6701                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation 
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

/*
 *	File:	enp.c		Module: HOST Resident
 *	ENP:	All ENP models
 *	Unix:	System V
 *
 *	This file implements the generic support procedures utilized by
 *	sock_driver.c. The only "dependent" portion for enp.c is which
 *	enp_addr.h file is included.
 */

 /*	HISTORY:
  *		Initial coding (for Sys V and ENP-30) July 1984 by John Mullen
  */

#include <sys/param.h>
#include <CMC/types.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/inode.h>
#include <sys/file.h>
#include <CMC/errno.h>
#include <CMC/signal.h>
#include "enp_addr.h"
#include <CMC/netbfr.h>
#include <CMC/ring.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/in.h>
#include <CMC/enp.h>


/*
 *	Useful constants
 */

# define K *1024
# define ENPBUFSIZE 1550

/*
 *	Globals
 */

SHARED_RINGS	*enp;			/* Pointer to ...		*/
SHARED_RINGS	enp_rings;		/* pointers to the rings	*/
CHAN		*data_chan;		/* Data channel array		*/
RING32		h_freebfr;		/* Our free buffer pool		*/

extern HOSTCTL	host;			/* Host/ENP initailization	*/

extern
unsigned long	MYHOSTPARAM;		/* Our Internet address		*/
extern char	MYNODEPARAM[];		/* Our Ethernet address		*/


/*
 *		enpservice()
 *
 *	The "real" interrupt routine - We service ENP interrupts by
 *	first returning any buffers found on the h_netcomplete ring to
 *	the h_freebfr ring. We then process any incoming buffers on the
 *	e_tohost ring (data from the network). The process wakeup and TCP
 *	urgent rings are serviced last.
 *
 *	Called from enpintr().
 */

enpservice()
{
	register CHAN	*cp;
	register RING	*rp;
	register BFR	*bp;
	register int	addr, x;

	if ((host.h_state & HS_INIT) == 0) {
		init_enp(1, 0);
		return;
	}

	x = ringempty(&h_freebfr);
	while (bp = (BFR *) ringget(enp->h_netcomplete)) {
		hostbfr(bp);
		ringput(&h_freebfr, bp);
	}
	if (x)
		wakeup(&h_freebfr);

	while (bp = (BFR *) ringget(enp->e_tohost)) {
		hostbfr(bp);
		cp = &data_chan[(short) bp->b_device];
		rp = (RING *) &cp->c_tohost;
		if (ringempty(rp))
			wakeup(rp);
		if (ringput(rp, bp) == 0)
			panic ("enpservice: ringput failed!");

#ifdef SELECT
		if (cp->c_selproc) {
			selwakeup(cp->c_selproc, ntohs(cp->c_state)&SS_SELCOLL);
			cp->c_selproc = 0;
			cp->c_state = htons(ntohs(cp->c_state) & SS_SELCOLL);
		}
#endif

	}
	
	while ((addr = ringget(enp->e_wakeaddr)) != 0)
		wakeup(addr);

	while ((cp = (CHAN *) ringget(enp->e_urg)) != 0)
		signal(cp->c_pgrp, SIGURGENT);
}


/*
 *		init_enp()
 *
 *	  The Host/ENP initialization "hand-shake" routine. This routine
 *	will be called twice - First time is from the device driver on
 *	the initial open; we set up some shared stuff and build the list
 *	of INTERFACE level protocols we want up in the ENP, we then
 *	interrupt the ENP (so it can initialize) and wait for it to
 *	signal completion by setting sp->enpbase to non-zero and doing
 *	a "wakeup" on the address of SHARED.
 *
 *	  Second entry is from the interrupt routine (with sp->enpbase
 *	non-zero); we do a wakeup on the shared pointer (which actually
 *	wakes up this routine! - which was sleeping from the first entry).
 *	On the second entry we will initialize our portion of the shared
 *	ring structure and using the buffer allocation from the ENP, build
 *	our free buffer pool (h_freebfr).
 */

init_enp(pass, pb)
register int	pass;
register PIB	*pb;
{
	register SHARED		*sp = (SHARED *) SHAREBASE;
	register SHARED_RINGS	*sr = (SHARED_RINGS *) (sp + 1);
	register PIB		*pb2 = (PIB *) (sr + 1);
	register PKT		*pp;
	register PROTO		*p;
	register int		x;

	int			nchan;

#ifdef VERBOSE
	printf("ENP Init Pass %d\n", pass);
#endif

	if (pass == 1) {		/* from the interrupt routine */
		wakeup(sp);
		return;
	}

	sp->hostbase = ENPBASE;
	sp->enpbase  = 0;

	nchan = 0;
	while (pb->pib_name[0] != 0) {
		p = (PROTO *) pffindtype(pb->pib_family, pb->pib_type);
		if (p) {
		 (   (  	/* Set host's variables for protocol		*/

			p->pr_channel = pb->pib_start;	/* Chan. offset	*/
			p->pr_next = pb->pib_start;	/* First alloc	*/
			p->pr_end = pb->pib_start + pb->pib_num;
			nchan += pb->pib_num;

			/* Set ENP's variables for protocol		*/

			pb2->pib_family = htons(pb->pib_family);
			pb2->pib_type = htons(pb->pib_type);
			pb2->pib_start = htons(pb->pib_start);
			pb2->pib_num = htons(pb->pib_num);
			enp_move(pb->pib_name, pb2->pib_name,
				 sizeof(pb2->pib_name));

			pb2++;
		}
		pb++;
	}
	pb2->pib_name[0] = 0;		/* Terminate list	*/

	intenp();			/* Interrupt ENP	*/

	x = splnet();
	while (sp->enpbase == 0)
		sleep(sp, PENP);
	splx(x);
	if (sp->status == -1)		/* ENP failed init	*/
		panic("ENP FAILED INIT");

	MYHOSTPARAM = ntohl(sp->inetaddr);
	enp_move(sp->enetaddr, MYNODEPARAM, 6);
	data_chan = (CHAN *) (sp->chanaddr);

/*	Copy in the ADDRESSES of the shared rings		*/

	enp = &enp_rings;
	enp->h_open         = sr->h_open;
	enp->h_tonet        = sr->h_tonet;
	enp->h_netcomplete  = sr->h_netcomplete;
	enp->e_tohost       = sr->e_tohost;
	enp->e_hostcomplete = sr->e_hostcomplete;
	enp->e_wakeaddr     = sr->e_wakeaddr;
	enp->e_urg          = sr->e_urg;

/*	Initialize our rings and buffers			*/

	ringinit(&h_freebfr, 32);
	ringinit(enp->h_open, 8);
	ringinit(enp->h_tonet, 16);
	ringinit(enp->h_netcomplete, 16);

	pp = (PKT *) sp->hostbfraddr;

#ifdef VERBOSE
	printf("Rings at 0x%x, Channels at 0x%x, %d Buffers at 0x%x\n",
		enp, data_chan, sp->numhostbfr, pp);
#endif

	for (x = sp->numhostbfr; x > 0; x--)
		ringput(&h_freebfr, pp++);

	for (x = 0; x < nchan; x++) {
		ringinit(&data_chan[(short) x].c_tohost, CHANSIZE);
		sringinit(x);
		data_chan[(short) x].c_state = 0;
	}

	host.h_state = HS_INIT;
}


/*
 *	Utility routines used by the driver, etc.
 */

/*
 *		get_buf()
 *
 *	Get a buffer from the free pool, if none available and "wait"
 *	specified, sleep till someone frees a buffer.
 */

get_buf(dontwait)
{
	register BFR	*bp;
	register int	x;

	x = splnet();
	if (ringempty(&h_freebfr))
		enpservice();
	while ((bp = (BFR *) ringget(&h_freebfr)) == 0) {
		if (dontwait != 0)	
			break;
		sleep(&h_freebfr, PENP);
	}
	splx(x);

	if (bp)
		bp->b_addr = (char *) (bp + 1);

	return ((int) bp);
}


/*
 *		fre_buf()
 *
 *	Return a buffer to the free pool, if pool was empty - do a
 *	wakeup on it.
 *
 *	NOTE: This routine is NOT used by the "main" routine which frees
 *	      buffers found on h_netcomplete - It is intended to be used
 *	      by routines which will only be freeing a single buffer.
 */

fre_buf(bp)
register BFR	*bp;
{
	register int	x;

	x = splnet();
	if (ringempty(&h_freebfr))
		wakeup(&h_freebfr);
	ringput(&h_freebfr, bp);
	splx(x);
}


/*
 *		enpbfr(bp)
 *
 *	Ensure correct byte/word ordering in BFR control fields in
 *	BFR going TO the ENP.
 */

enpbfr(bp)
register BFR	*bp;
{
	bp->b_flags = htons(bp->b_flags);
	bp->b_len = htons(bp->b_len);
	bp->b_msglen = htons(bp->b_msglen);
	bp->b_level = htons(bp->b_level);
	bp->b_device = htons(bp->b_device);
	return ((int) bp);
}


/*
 *		hostbfr(bp)
 *
 *	Ensure correct byte/word ordering in BFR control fields in
 *	BFR coming FROM the ENP.
 */

hostbfr(bp)
register BFR	*bp;
{
	bp->b_flags = ntohs(bp->b_flags);
	bp->b_len = ntohs(bp->b_len);
	bp->b_msglen = ntohs(bp->b_msglen);
	bp->b_level = ntohs(bp->b_level);
	bp->b_device = ntohs(bp->b_device);
}


/*
 *		to_enp()
 *
 *	Send BFR to the ENP by placing it into the proper ring.
 */

to_enp(rp, bp)
register RING	*rp;
register BFR	*bp;
{
	register int	x;

	x = splnet();
	while (ringfull(rp))
		sleep(rp, PENP);
	splx(x);

	ringput(rp, enpbfr(bp));
}


enp_move(src, dest, cnt)
register char	*src;
register char	*dest;
register int	cnt;
{
	while (cnt--)
		*dest++ = *src++;
}


enp_zero(dest, cnt)
register char	*dest;
{
	while (cnt--)
		*dest++ = 0;
}
 pass);
#endif

	if (pass == 1) {		/* from the interrupt routine */
		wakeup(sp);
		return;
	}

	sp->hostbase = ENPBASE;
	sp->enpbase  = 0;

	nchan = 0;
	while (pb->pib_name[0] != 0) {
		p = (PROTO *) pffindtype(pb->pib_family, pb->pib_type);
		if (p) {
		unix/sys/enpram.c                                                                                      644     322     145         1535  3621344307   7363                                                                                                                                                                                                                                                                                                                                                                      #include <sys/param.h>
#include <sys/types.h>
#include <sys/dir.h>
#include <sys/file.h>
#include <sys/signal.h>
#include <CMC/errno.h>
#include <sys/user.h>
#include <CMC/enpram.h>

#include "enp_addr.h"
#include "copyin.h"

#define ENPVADDR	(ENP_VADDR + 0x1000)
#define GOCMD		0x8080


enpropen()
{}

enprclose()
{}

enprread()
{
	if (u.u_count > 0) {
		if (copyout(ENPVADDR + u.u_offset, u.u_base, u.u_count) != 0)
			u.u_error = EFAULT;

		u.u_base += u.u_count;
		u.u_count = 0;
	}
}

enprwrite()
{
	if (u.u_count > 0) {
		if (copyin(u.u_base, ENPVADDR + u.u_offset, u.u_count) != 0)
			u.u_error = EFAULT;

		u.u_base += u.u_count;
		u.u_count = 0;
	}
}

enprioctl(dev, cmd, arg, mode)
{
	switch (cmd) {
	case ENPIOC_JUMP:		/* Go command */
		enpgo(ENP_VADDR, arg);
		break;

	case ENPIOC_RESET:		/* reset command */
		resetenp(ENP_VADDR);
		break;
	}

}
*	Copy in the ADDRESSES of the shared rings		*/

	enp = &enp_rings;
	enp->h_open         = sr->h_open;
	enp->h_tonet        = sr->h_tonet;
	enp->h_netcomplete  = sunix/sys/eth_proto.c                                                                                   444     322     145         4770  3621344310  10100                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

#include <CMC/types.h>
#include <CMC/errno.h>
#include <CMC/ring.h>
#include <CMC/netbfr.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/eth_proto.h>
#include <CMC/eth.h>
#include <CMC/enp.h>

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>


/*
 *	Defines for types, header/data offsets in protosw
 */

# define MAX_ETH_HDR	0		/* Where data starts	*/
# define MAX_ETH_DATA	1514		/* Max. size of it	*/


/*
 *	External Globals we use
 */

extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;


extern	eth_cmp(), ethnmchk(), ethgname();
extern	ethbind(), ethconnect(), ethclose(), ethsend(), ethrecv();


/*
 *	The protocol switch table ...
 */

struct protosw ethsw[] = {
	{ SOCK_RAW, PF_ETHER, ETHPROTO_RAW, PR_ATOMIC|PR_ADDR,
	  eth_cmp, ethnmchk, ethgname,
	  ethbind, ethconnect, ethclose, ethsend, ethrecv,
	  0, 0, 0, MAX_ETH_HDR, MAX_ETH_DATA }
};


/*
 *	The Ethernet domain ...
 */

struct domain ethdomain = {
	AF_ETHER, "ethernet", ethsw, &ethsw[sizeof(ethsw)/sizeof(ethsw[0])]
};


/*
 *	"Generic" Ethernet routines
 */

en_addr	MYNODEPARAM;

static
en_addr	zero_addr = {0};


static
eth_cmp(inp1, inp2, len, reuse)
register sockaddr_eth *inp1, *inp2;
{
	if (inp1->sen_type && (inp1->sen_type == inp2->sen_type))
		return (EADDRINUSE);

	return (0);
}


ethgname(s, place)
register SOCKET	*s;
{
	register sockaddr_eth *csen;

	if (s->so_state & SS_BOUND)
		enp_move(s->so_name, place, sizeof(sockaddr_eth));
	else
		enp_zero(place, sizeof(sockaddr_eth));

	if (s->so_state & SS_CONNECTED) {
		register sockaddr_eth *ap;

		ap = (sockaddr_eth *) place + 1;
		ap->sen_family = s->so_proto->pr_family;
		csen = (sockaddr_eth *) data_chan[(short) s->so_enpid].c_name;
		ap->sen_type = ntohs(csen->sen_type);
		memcpy(&ap->sen_addr, &csen->sen_addr, sizeof(en_addr));
	}
	else
		enp_zero((sockaddr_eth *) place + 1, sizeof(sockaddr_eth));

	return (sizeof(sockaddr_eth));
}


ethnmchk(s)
register SOCKET	*s;
{
	register sockaddr_eth *sep;
	register unsigned short type;

	extern en_addr MYNODEPARAM;

	sep = (sockaddr_eth *) s->so_name;

	if ((type = sep->sen_type) == 0)
		return (EADDRNOTAVAIL);

	if (memcmp(&sep->sen_addr, &zero_addr, sizeof(zero_addr)) == 0)
		memcpy(&sep->sen_addr, &MYNODEPARAM, sizeof(en_addr));

	return (0);
}
fer.
 */unix/sys/if_eth.c                                                                                      444     322     145         3153  3621344310   7325                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */


#include <CMC/types.h>
#include <CMC/errno.h>
#include <CMC/ring.h>
#include <CMC/netbfr.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/eth_proto.h>
#include <CMC/eth.h>
#include <CMC/enp.h>

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>


/*
 *		if_eth.c
 *
 *	Raw Ethernet routines - Called through protocol switch ethsw[].
 *	We use sockaddr_in.sin_port to hold the Ethernet packet type
 *	for the Raw Ethernet interface.
 *
 *	ethbind()
 *	ethconnect()
 *	ethclose()
 *	ethsend()
 *	ethrecv()
 */


extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;


ethbind(s)
register SOCKET	*s;
{
	register sockaddr_eth	*sen, *sen2;

	if ((s->so_state & SS_RESV) == 0)
		return (EINVAL);

	sen2 = (sockaddr_eth *) (dat (   (  a_chan[(short) s->so_enpid].c_name) + 1;
	sen = (sockaddr_eth *) s->so_name;
	enp_move(&sen->sen_addr, &sen2->sen_addr, sizeof(en_addr));
	sen2->sen_type = htons(sen->sen_type);

	s->so_state |= SS_CONNECTED;
	return (0);
}


ethconnect(s, to, type, flags)
register SOCKET		*s;
register sockaddr_eth	*to;
{
	return (0);
}


ethclose(s)
register SOCKET	*s;
{
	register CHAN	*cp;

	cp = &data_chan[(short) s->so_enpid];

	while (htons(cp->c_inflight) > 0);
	enp_zero(cp->c_name, SOCKNAMESIZE);
	cp->c_state = SS_AVAIL;
}


ethsend(s)
register SOCKET	*s;
{
	return (0);
}


ethrecv(s)
register SOCKET	*s;
{
	return (0);
}
ocol switch ethsw[].
 *	We use sockaddr_in.sin_port to hold the Ethernet packet type
 *	for the Raw Ethernet interface.
 *
 *	ethbind()
 *	ethconnect()
 *	ethclose()
 *	ethsend()
 *	ethrecv()
 */


extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;


ethbind(s)
register SOCKET	*s;
{
	register sockaddr_eth	*sen, *sen2;

	if ((s->so_state & SS_RESV) == 0)
		return (EINVAL);

	sen2 = (sockaddr_eth *) (datunix/sys/if_rip.c                                                                                      444     322     145         4341  3621344311   7340                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */


#include <CMC/types.h>
#include <CMC/errno.h>
#include <CMC/ring.h>
#include <CMC/netbfr.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/in.h>
#include <CMC/enp.h>

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>


/*
 *		if_rip.c
 *
 *	RIP specific routines - Called through protocol switch inetsw[].
 *	We use sockaddr_in.sin_port to hold the upper-level protocol number
 *	for the Raw Internet interface.
 *
 *	ripnmchk()
 *	ripbind()
 *	ripconnect()
 *	ripclose()
 *	ripsend()
 *	riprecv()
 */


extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;

extern HOST	MYHOSTPARAM;

static
sockaddr_in	sin = {AF_INET};


ripnmchk(s)
register SOCKET	*s;
{
	return (0);
}


ripbind(s)
register SOCKET	*s;
{
	register sockaddr_in	*sin, *sin2;

	if ((s->so_state & SS_RESV) == 0)
		return (EINVAL);

	sin2 = (sockaddr_in *) (data_chan[(short) s->so_enpid].c_name) + 1;
	sin = (sockaddr_in *) s->so_name;
	sin2->sin_addr.s_addr = htonl(sin->sin_addr.s_addr);
	sin2->sin_port = htons(IPPROTO_RAW);
	return (0);
}


ripconnect(s, to, type, flags)
register SOCKET		*s;
register sockaddr_in	*to;
{
	register sockaddr_in	*sin;

	if (to->sin_addr.s_addr == 0) {
		u.u_error = EINVAL;
		return;
	}

	/*	Set foreign host/protocol in channel	*/

	sin = (sockaddr_in *) data_chan[(short) s->so_enpid].c_name;
	sin->sin_addr.s_addr = htonl(to->sin_addr.s_addr);
	sin->sin_port = htons(IPPROTO_RAW);

	/*	Set foreign host/protocol in socket		*/

	sin = (sockaddr_in *) (s->so_name) + 1;
	sin->sin_addr.s_addr = to->sin_addr.s_addr;
	sin->sin_port = IPPROTO_RAW;

	s->so_state |= SS_CONNECTED;

	return (0);
}


ripclose(s)
register SOCKET	*s;
{
	register CHAN	*cp;

	cp = &data_chan[(short) s->so_enpid];

	while (htons(cp->c_inflight) > 0);
	enp_zero(cp->c_name, SOCKNAMESIZE);
	cp->c_state = SS_AVAIL;
}


ripsend(s)
register SOCKET	*s;
{
	register sockaddr_in	*sin;

	sin = (sockaddr_in *) (s->so_name) + 1;
	return ((int) sin);
}


riprecv(s)
register SOCKET	*s;
{
	return (0);
}
short type;

	extern en_addr MYNODEPARAM;

	sep = (sockaddr_eth *) s->so_name;

	if ((type = sep->sen_type) == 0)
		return (EADDRNOTAVAIL);

	if (memcmp(&sep->sen_addr, &zero_addr, sizeof(zero_addr)) == 0)
		memcpy(&sep->sen_addr, &MYNODEPARAM, sizeof(en_addr));

	return (0);
}
fer.
 */unix/sys/if_udp.c                                                                                      444     322     145         4111  3621344312   7332                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */


#include <CMC/types.h>
#include <CMC/errno.h>
#include <CMC/ring.h>
#include <CMC/netbfr.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/in.h>
#include <CMC/enp.h>

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>


/*
 *		if_udp.c
 *
 *	UDP specific routines - Called through protocol switch inetsw[].
 *
 *	udpbind()
 *	udpconnect()
 *	udpclose()
 *	udpsend()
 *	udprecv()
 */


extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;
extern HOST	MYHOSTPARAM;

static
sockaddr_in	sin = {AF_INET};


udpbind(s)
register SOCKET	*s;
{
	register sockaddr_in	*sin, *sin2;

	if ((s->so_state & SS_RESV) == 0)
		return (EINVAL);

	sin2 = (sockaddr_in *) (data_chan[(short) s->so_enpid].c_name) + 1;
	sin = (sockaddr_in *) s->so_name;
	sin2->sin_addr.s_addr = htonl(sin->sin_addr.s_addr);
	sin2->sin_port = htons(sin->sin_port);
	return (0);
}


udpconnect(s, to, type, flags)
register SOCKET		*s;
register sockaddr_in	*to;
{
	register sockaddr_in	*sin;

	if ((to->sin_port == 0) || (to->sin_addr.s_addr == 0)) {
		u.u_error = EINVAL;
		return;
	}

	/*	Set foreign host/port in channel	*/

	sin = (sockaddr_in *) data_chan[(short) s->so_enpid].c_name;
	sin->sin_addr.s_addr = htonl(to->sin_addr.s_addr);
	sin->sin_port = htons(to->sin_port);

	/*	Set foreign host/port in socket		*/

	sin = (sockaddr_in *) (s->so_name) + 1;
	sin->sin_addr.s_addr = to->sin_addr.s_addr;
	sin->sin_port = to->sin_port;

	s->so_state |= SS_CONNECTED;
	return (0);
}


udpclose(s)
register SOCKET	*s;
{
	register CHAN	*cp;

	cp = &data_chan[(short) s->so_enpid];

	while (htons(cp->c_inflight) > 0);
	enp_zero(cp->c_name, SOCKNAMESIZE);
	cp->c_state = SS_AVAIL;
}


udpsend(s)
register SOCKET	*s;
{
	register sockaddr_in	*sin;

	sin = (sockaddr_in *) (s->so_name) + 1;
	return ((int) sin);
}


udprecv(s)
register SOCKET	*s;
{
	return (0);
}
ET	*s;
{
	register sockaddr_in	*sin;

	sin = (sockaddr_in *) (s->so_name) + 1;
	return ((int) sin);
}


riprecv(s)
register SOCKET	*s;
{
	return (0);
}
short type;

	extern en_addr MYNODEPARAM;

	sep = (sockaddr_eth *) s->so_name;

	if ((type = sep->sen_type) == 0)
		return (EADDRNOTAVAIL);

	if (memcmp(&sep->sen_addr, &zero_addr, sizeof(zero_addr)) == 0)
		memcpy(&sep->sen_addr, &MYNODEPARAM, sizeof(en_addr));

	return (0);
}
fer.
 */unix/sys/in_proto.c                                                                                    444     322     145        10051  3725137136   7746                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

#include <CMC/types.h>
#include <CMC/errno.h>
#include <CMC/ring.h>
#include <CMC/netbfr.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/in.h>
#include <CMC/enp.h>

#include <sys/param.h>
#include <sys/signal.h>
#include <sys/dir.h>
#include <sys/user.h>


/*
 *	The following defines for MAXs are temporary - these values
 *	will be provided by the protocol running in the ENP at init
 *	time. (soon)
 */


/*
 *	TCP Specific
 */

#define	MAX_TCP_HDR	54		/* LOCAL + INHDR + TCPHDR	*/
#define MAX_TCP_DATA	1460		/* Max Ether - Max TCP/IP Hdr	*/

extern	tcpbind(), tcpconnect(), tcpclose(), tcpsend(), tcprecv();


/*
 *	UDP Specific
 */

#define	MAX_UDP_HDR	42		/* LOCAL + INHDR + UDHDR	*/
#define	MAX_UDP_DATA	1472		/* Max Ether - Max UDP/IP Hdr	*/

extern	udpbind(), udpconnect(), udpclose(), udpsend(), udprecv();


/*
 *	RIP Specific (Raw IP)
 */

#define	MAX_RIP_HDR	34		/* LOCAL + INHDR		*/
#define	MAX_RIP_DATA	1480		/* Max Ether - Max IP hdr	*/

extern	ripnmchk();
extern	ripbind(), ripconnect(), ripclose(), ripsend(), riprecv();


/*
 *	Generic
 */

extern	ip_cmp();
extern	ipgname(), ipnmchk();


/*	The protocol switch		*/

struct protosw	inetsw[] = {
	{ SOCK_STREAM, PF_INET, IPPROTO_TCP, PR_CONNREQUIRED,
	  ip_cmp, ipnmchk, ipgname,
	  tcpbind, tcpconnect, tcpclose, tcpsend, tcprecv,
	  0, 0, 0, MAX_TCP_HDR, MAX_TCP_DATA },

	{ SOCK_DGRAM, PF_INET, IPPROTO_UDP, PR_ATOMIC,
	  ip_cmp, ipnmchk, ipgname,
	  udpbind, udpconnect, udpclose, udpsend, udprecv,
	  0, 0, 0, MAX_UDP_HDR, MAX_UDP_DATA },

	{ SOCK_RAW, PF_INET, IPPROTO_RAW, PR_ATOMIC,
	  ip_cmp, ripnmchk, ipgname,
	  ripbind, ripconnect, ripclose, ripsend, riprecv,
	  0, 0, 0, MAX_RIP_HDR, MAX_RIP_DATA }
};


/*	The Protocol Domain	*/

struct domain	inetdomain = {
	AF_INET, "internet", inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])]
};


/*
 *	Generic INET name routines
 */

static
ip_cmp(inp1, inp2, len, reuse)
register sockaddr_in *inp1, *inp2;
{
	if (inp1->sin_port && ((inp1->sin_port == inp2->sin_port) && !reuse))
		return (EADDRINUSE);
	return (0);
}


extern
SHARED_RINGS	*enp;

extern CHAN	*data_chan;
HOST	MYHOSTPARAM;

static
sockaddr_in	sin = {AF_INET};


ipgname(s, place)
register SOCKET	*s;
{
	register sockaddr_in *csin;

	if (s->so_state & SS_BOUND)
		enp_move(s->so_name, place, sizeof(socka (   (  ddr_in));
	else
		enp_zero(place, sizeof(sockaddr_in));

	if (s->so_state & SS_CONNECTED) {
		register sockaddr_in *ap;

		ap = (sockaddr_in *) place + 1;
		ap->sin_family = s->so_proto->pr_family;
		csin = (sockaddr_in *) data_chan[(short) s->so_enpid].c_name;
		ap->sin_port = ntohs(csin->sin_port);
		ap->sin_addr.s_addr = ntohl(csin->sin_addr.s_addr);
	}
	else
		enp_zero((sockaddr_in *) place + 1, sizeof(sockaddr_in));

	return (sizeof(sockaddr_in));
}


ipnmchk(s)
register SOCKET	*s;
{
	register sockaddr_in *inp;
	register short try, inc, current;
	static	 short curr_priv = IPPORT_RESERVED,
		curr_unpriv = IPPORT_RESERVED;

# define bounded(x) ((x>IPPORT_RESERVED/2)&&(x<IPPORT_RESERVED*2))

	inp = (sockaddr_in *) s->so_name;
	if (inp->sin_addr.s_addr == 0)
		inp->sin_addr.s_addr = MYHOSTPARAM;

	if (inp->sin_port == 0) { 	/* we'll pick one */
		if ( u.u_uid == 0 ) {
			current = curr_priv;
			inc = -1;
		}
		else {
			current = curr_unpriv;
			inc = 1;
		}
		for (try = current+inc; bounded(try); try += inc) { 
			sin.sin_port = try;
			if (namecheck(s->so_proto, &sin, sizeof (sin)) == 0)
				goto gotone;
		}
		for (try = IPPORT_RESERVED+inc; try != current; try += inc) { 
			sin.sin_port = try;
			if (namecheck(s->so_proto, &sin, sizeof (sin)) == 0)
				goto gotone;
		}
		/* if we get here, failure */
		return (EADDRNOTAVAIL);

gotone:
		inp->sin_port = try;
		s->so_nmlen = sizeof(sin);
		if ( u.u_uid == 0 )
			curr_priv = try;
		else	curr_unpriv = try;
	}

	if ((inp->sin_port < IPPORT_RESERVED) && (u.u_uid != 0))
		return (EACCES);
	return (0);
}
0, MAX_TCP_HDR, MAX_TCP_DATA },

	{ SOCK_DGRAM, PF_INET, IPPROTO_UDP, PR_ATOMIC,
	  ip_cmp, ipnmchk, ipgname,
	  udpbind, udpconnect, udpclose, udpsend, udprecv,
	  0, 0, 0, MAX_UDP_HDR, MAX_UDP_DATA },

	{ SOCK_RAW, PF_INET, IPPROTO_RAW, PR_ATOMIC,
	  ip_cmp, ripnmchk, ipgname,
	  ripbind, ripconnect, ripclose, ripsend, riprecv,
	  0, 0, 0, MAX_RIP_HDR, MAX_RIP_DATA }
};


/*	The Protocol Domain	*/

struct domain	inetdomain = {
	AF_INET, "internet", inetsw, &inetsw[unix/sys/pty.c                                                                                         444     322     145        16616  3621344313   6736                                                                                                                                                                                                                                                                                                                                                                      /*
 *	Copyright (c) 1984, Communication Machinery Corporation
 */

/*
 *	This file contains material and information which is
 *	proprietary to Communication Machinery Corporation, and
 *	which may not be divulged without the express written
 *	permission of Communication Machinery Corporation.
 */

/*
 *	Pseudo-teletype driver. This is really two drivers, requiring
 *	two entries in cdevsw.
 *
 *	New implementation for Sys V, includes 4.2BSD PKT mode.
 */

# include <sys/types.h>
# include <sys/param.h>
# include <sys/dir.h>
# include <sys/signal.h>
# include <sys/user.h>
# include <CMC/errno.h>
# include <sys/file.h>
# include <sys/termio.h>
# include <sys/conf.h>
# include <sys/tty.h>
# include <sys/sysmacros.h>
# include <CMC/pty.h>
# include "copyin.h"

struct tty pt_tty[NPTY];
static char ptychars[2*NPTY];

/*
 *	"Slave" side.  Shows up as /dev/ttyp?, and can be used as
 *	a normal tty device.
 */

ptsopen (dev, flag)
{
	register struct tty *tp;

	if (minor (dev) > NPTY ) {
		u.u_error = ENXIO;
		return;
	}

	tp = &pt_tty[(short) minor(dev)];
	if ( (tp->t_state&ISOPEN) == 0 ) {
		ttinit (tp);
		tp->t_cflag &= ~CBAUD;
		tp->t_cflag |= EXTB;
	}
	
	while ( (tp->t_state & CARR_ON) == 0 ) {
		tp->t_state |= WOPEN;
		sleep ((caddr_t)&tp->t_rawq, TTIPRI);
	}

	(*linesw[tp->t_line].l_open)(tp);

	if ( tp->t_tbuf.c_ptr == NULL ) {
		tp->t_tbuf.c_ptr = &ptychars[(short)minor(dev)*2];
		tp->pt_send = tp->pt_flags = 0;
		wakeup (&tp->t_tbuf.c_ptr);
	}

	wakeup ((caddr_t)&tp->t_rawq);
}

ptsclose (dev)
{
	register struct tty *tp;

	tp = &pt_tty[(short) minor(dev)];
	ttywait (tp);
	tp->pt_send = tp->pt_flags = 0;
	tp->t_tbuf.c_ptr = NULL;
	(*linesw[tp->t_line].l_close)(tp);
	wakeup (&tp->t_outq.c_cf);
}

ptsread (dev)			/* normally never called */
{
	register struct tty *tp;

	tp = &pt_tty[(short) minor(dev)];

	if ((tp->t_state&ISOPEN) == 0 ) {
		u.u_error = ENODEV;
		return;
	}

	if ( u.u_fmode&FNDELAY && (tp->t_rawq.c_cc == 0) ) {
		u.u_error = EWOULDBLOCK;
		return;
	}

	(*linesw[tp->t_line].l_read)(tp);
}

ptswrite (dev)			/* normally never called */
{
	register struct tty *tp;

	tp = &pt_tty[(short) minor(dev)];

	if ( (tp->t_state&ISOPEN) == 0) {
		u.u_error = ENODEV;
		return;
	}

	if ( u.u_fmode&FNDELAY && tp->t_state&OASLP ) {
		u.u_error = EWOULDBLOCK;
		return;
	}

	(*linesw[tp->t_line].l_write)(tp);
}

ptsioctl (dev, cmd, arg, mode)
{
	register struct tty *tp;

	tp = &pt_tty[(short) minor(dev)];

	if ( (tp->t_state&ISOPEN) == 0) {
		u.u_error = ENODEV;
		return;
	}

	ttiocom (tp, cmd, arg, mode);

	if (tp->pt_flags&PF_NOSTOP) {
		if (tp->t_iflag&IXON) {		/* ^S/^Q enabled */
			tp->pt_send &= ~TIOCPKT_NOSTOP;
			tp->pt_send |= TIOCPKT_DOSTOP;
			tp->pt_flags &= ~PF_NOSTOP;
			wakeup ((caddr_t)&tp->t_outq.c_cf);
		}
	} else {
		if ( (tp->t_iflag&IXON) == 0 ) {
			tp->pt_send &= ~TIOCPKT_DOSTOP;
			tp->pt_send |= TIOCPKT_NOSTOP;
			tp->pt_flags |= PF_NOSTOP;
			wakeup ((caddr_t)&tp->t_outq.c_cf);
		}
	}
}

ptyproc (tp, cmd)
register struct tty *tp;
{
	if ( tp->t_state & ISOPEN )
	switch (cmd) {
	case T_OUTPUT:
	start:
		if (tp->t_state&TTSTOP)
			break;
		if (tp->pt_flags&PF_STOPPED) {
			tp->pt_flags &= ~PF_STOPPED;
			tp->pt_send = TIOCPKT_START;
		}
		if (tp->t_outq.c_cc) {
			wakeup ((caddr_t)&tp->t_outq.c_cf);
			tp->t_state |= BUSY;
		}
		break;

	case T_SUSPEND:
		tp->t_state |= TTSTOP;
		tp->pt_flags |= PF_STOPPED;
		tp->pt_send |= TIOCPKT_STOP;
		break;

	case T_WFLUSH:
		tp->pt_send |= TIOCPKT_FLUSHWRITE;
	case T_RESUME:
		tp->t_state &= ~TTSTOP;
		goto start;

	case T_RFLUSH:
		tp->pt_send |= TIOCPKT_FLUSHREAD;
		break;
	}
}



/*
 *	"Controller" side.  This is considerably more complicated
 *	than the slave side, mostly because it has to spend time
 *	defeating the line discipline operation.
 *
 *	Shows up as /dev/ptyp?
 *
 *	NOTE: the cdevsw entry for the controller MUST NOT have
 *	a tty struct array associated with it.
 *
 */

ptcopen (dev, flag)
{
	register struct tty *tp;

	if (minor(dev) > NPTY) {
		u.u_error = ENXIO;
		return;
	}

	tp = &pt_tty[(short) minor(dev)];
	if ( tp->t_state & CARR_ON ) {		/* already opened */
		u.u_error = EIO;
		return;
	}

	tp->t_proc = ptyproc;
	if (tp->t_state&WOPEN)
		wakeup ((caddr_t)&tp->t_rawq);
	tp->t_state |= CARR_ON;
}

ptcclose (dev)
{
	register struct tty *tp;

	tp = &pt_tty[(short) minor(dev)];

	if (tp->t_state & ISOPEN)
		signal (tp->t_pgrp, SIGHUP);
	ttyflush (tp, FREAD|FWRITE);
	tp->t_state &= ~(CARR_ON | ISOPEN);
	tp->t_state = 0;
}

ptcwrite (dev)
{
	register struct tty *tp;
	register char *cp;
	register struct cblock *cb;
	register int n;

	tp = &pt_tty[(short) minor(dev)];
	if ((tp->t_state&ISOPEN) == 0) {
		u.u_error = EIO;
		return;
	}

	while (tp->t_rbuf.c_ptr == NULL) {
		cb = getcf();
		if ( cb == NULL ) {
			cfreelist.c_flag = 1;
			sleep ((caddr_t)&cfreelist, TTOPRI);
		}
		else {
			tp->t_rbuf.c_ptr = cb->c_data;
			tp->t_rbuf.c_size = cfreelist.c_size;
			tp->t_rbuf.c_count = tp->t_rbuf.c_size;
		}
	}

	while (u.u_count) {
		n = min(tp->t_rbuf.c_count, u.u_count);
		cp = tp->t_rbuf.c_ptr + (tp->t_rbuf.c_size -
						tp->t_rbuf.c_count);
		copyin (u.u_base, cp, n);
		tp->t_rbuf.c_count -= n;
		u.u_count -= n;
		u.u_base += n;

		(*linesw[tp->t_line].l_input) (tp, 0);
	}
}

ptcread (dev)
{
	register struct tty *tp;
	register struct cblock *cb;
	register int n;
	register int c;

	tp = &pt_tty[(short) minor(dev)];

again:
	if ((tp->t_state&ISOPEN) == 0) {
		u.u_error = EIO;
		goto out;
	}

	if ( (tp->t_state&TTSTOP) || (tp->t_outq.c_cc == 0) ) {
		if ( u.u_fmode&FNDELAY) {
			u.u_error = EWOULDBLOCK;
			return;
		}
		sleep ((caddr_t)&tp->t_outq.c_cf, TTIPRI);
		goto again;
	}

	if (tp->pt_flags&PF_PKT) {
		if (tp->pt_send) {
			passc (tp->pt_send);
			tp->pt_send = 0;
			return;
		}
		else	passc (0);
	}

	while ( tp->t_outq.c_cc && u.u_count ) {
		cb = tp->t_outq.c_cf;
		n = cb->c_last - cb->c_first;
		if ( u.u_count >= n ) {
			copyout (&cb->c_data[cb->c_first], u.u_base, n);
			u.u_base += n;
			u.u_count -= n;
			putcf (getcb (&tp->t_outq));
		} else {
			if ( (c = getc (&tp->t_outq)) < 0 )
				break;
			passc (c);
		}
	}

out:
	tp->t_state &= ~BUSY;

	if (tp->t_state&OASLP) {
		if (tp->t_outq.c_cc <= ttlowat[tp->t_cflag&CBAUD]) {
			tp->t_state &= ~OASLP;
			wakeup ((caddr_t) &tp->t_outq);
		}
	}
	if (tp->t_state&TTIOW) {
		if (tp->t_outq.c_cc == 0) {
			tp->t_state &= ~TTIOW;
			wakeup ((caddr_t)&tp->t_oflag);
		}
	}
}

ptcioctl (dev, cmd, arg, mode)
{
	register struct tty *tp;
	register v;

	tp = &pt_tty[(short) minor(dev)];

	while ( tp->t_tbuf.c_ptr == NULL )
		sleep ( &tp->t_tbuf.c_ptr, TTOPRI );

	switch (cmd) {
	case TIOCPKT:
		v = fuword( arg );
		if ( v == -1 ) {
			u.u_error = EFAULT;
			return;
		}
		if ( v )
			tp->pt_flags |= PF_PKT;
		else	tp->pt_flags &= ~PF_PKT;
		return;

	case TIOCREMOTE:
		v = fuword( arg );
		if ( v == -1 ) {
			u.u_error = EFAULT;
			return;
		}
		if ( v )
			tp->pt_flags |= PF_REMOTE;
		else	tp->pt_flags &= ~PF_REMOTE;
		ttyflush (tp, FREAD|FWRITE);
		return;

/*
	case TIOCSETP:
		while (getc (&tp->t_outq) >= 0)
			;
		break;
*/
	}

	ttiocom (tp, cmd, arg, mode);

	if (tp->pt_flags&PF_NOSTOP) {
		if (tp->t_iflag&IXON) {		/* ^S/^Q enabled */
			tp->pt_send &= ~TIOCPKT_NOSTOP;
			tp->pt_send |= TIOCPKT_DOSTOP;
			tp->pt_flags &= ~PF_NOSTOP;
			wakeup ((caddr_t)&tp->t_outq.c_cf);
		}
	} else {
		if ( (tp->t_iflag&IXON) == 0 ) {
			tp->pt_send &= ~TIOCPKT_DOSTOP;
			tp->pt_send |= TIOCPKT_NOSTOP;
			tp->pt_flags |= PF_NOSTOP;
			wakeup ((caddr_t)&tp->t_outq.c_cf);
		}
	}
}

ptcselect()
{
	panic ("ptcselect");
}
		unsigned long e_silo_underrun;
.br
				/* xmit data fetch failed */
.br
		unsigned long e_late_coll;
.br
				/*  (   (  unix/sys/ring.c                                                                                        444     322     145         2234  3711530644   7034                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

#include <CMC/ring.h>

/* 
 * routines to synchronize enp and host 
 */

ringinit( rp,size )
register RING *rp;
{
	rp->r_rdidx = rp->r_wrtidx= 0;
	rp->r_size = size;
}

ringempty( rp )
register RING *rp;
{
	return( rp->r_rdidx == rp->r_wrtidx );
}

ringfull( rp )
register RING *rp;
{
	register short idx;

	idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
	return( idx == rp->r_rdidx );
}

ringput( rp,v )
register RING *rp;
{
	register int idx;

	idx = (rp->r_wrtidx + 1) & (rp->r_size-1);
	if( idx != rp->r_rdidx )
	{
		rp->r_slot[ rp->r_wrtidx ] = v;
		rp->r_wrtidx = idx;
		return( 1 );
	}
	return( 0 );
}

ringget( rp )
register RING *rp;
{
	register int i = 0;

	if( rp->r_rdidx != rp->r_wrtidx )
	{
		i = rp->r_slot[ rp->r_rdidx ];
		rp->r_rdidx = (rp->r_rdidx + 1) & (rp->r_size - 1);
	}
	return( i );
}

fir( rp )
register RING *rp;
{
	if( rp->r_rdidx != rp->r_wrtidx )
		return( rp->r_slot[ rp->r_rdidx ] );
	else
		return( 0 );
}
p->t_state & CARR_ON) == 0 ) {
		tp->t_state |= WOPEN;
		sleep ((caddr_t)&tp->t_rawq, TTIPRI);
	}

	(*linesw[tp->t_line].l_open)(tp);

	if ( tp->t_tbuf.c_ptr == NULL ) {
		tp->t_tbuf.c_ptr = &ptychars[(short)minor(dev)*2];
		tp->pt_send = tp->pt_flags = 0;
		wakeup (&tp->t_tbuf.c_ptr);
	}

	wakeup ((caddr_t)&tp->t_rawq);
}

ptsclose (dev)
{
	register strunix/sys/enp_addr.h                                                                                    444     322     145          465  3621344317   7642                                                                                                                                                                                                                                                                                                                                                                      /*
 *	ENP address definitions:
 *
 *		ENP_VADDR	ENP (as 128k memory) in kernel's memory
 *				mapped space.
 *
 *		ENPBASE		Start of ENP memory (same as above).
 *
 *		SHAREBASE	Start of Host/ENP shared space.
 */

# define ENP_VADDR	0x7E0000

# define ENPBASE	ENP_VADDR
# define SHAREBASE	(ENPBASE + 0x1200)
t 
 */

ringinit( rp,size )
register RING *rp;
{
	rp->r_rdidx = rp->r_wrtidx= 0;
	rp->r_size = size;
}

ringempty( rp )
register RING *rp;
{
	return( rp->r_rdidx == rp->r_wrtidx );
}

ringfull( rp )
regiunix/sys/sock_driver.c                                                                                 444     322     145        42103  3725171016  10425                                                                                                                                                                                                                                                                                                                                                                      /*	Copyright (c) 1984 by Communication Machinery Corporation
 *
 *	This file contains material which is proprietary to
 *	Communication Machinery Corporation (CMC) and which
 *	may not be divulged without the written permission
 *	of CMC.
 */

/*
 *	File: sock_driver.c	Module(s): HOST Resident
 *
 *	This file implements a device driver for a CMC
 *	ENP.  The device driver supports the semantics
 *	of the Berkeley 4.2BSD socket abstraction as applied
 *	to the AF_INET domain.
 *
 *	Most of the socket-related support work is handled
 *	by code running on the ENP; only enough mechanism remains
 *	to allow simple questions to be answered simply.
 *
 *	The design is an overweight kluge, requiring one special
 *	file per socket.  The big advantage of this is that it
 *	will work on all (non-4.2) Unix systems; for 4.2 systems
 *	there is a different driver that replaces the kernel
 *	support for the AF_INET protocol suite.
 */

/*	HISTORY:
		initial coding July 1984 by John Mullen
		Added generic DMA capability -- 12/18/84 by jrm
		Rev_B Modified - CMC Staff - 4/85
 */

#include <sys/param.h>
#include <sys/sysmacros.h>
#include <CMC/types.h>
#include <sys/dir.h>
#include <CMC/signal.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/file.h>
#include <CMC/longnames.h>
#include <CMC/netbfr.h>
#include <CMC/ring.h>
#include <CMC/CMC_proto.h>
#include <CMC/CMC_socket.h>
#include <CMC/in.h>
#include <CMC/enp.h>
#include <CMC/user_socket.h>
#include <CMC/errno.h>


/*
 *	Initialization & Interface Globals
 */

HOSTCTL		 host;

extern
SHARED_RINGS	*enp;			/* Pointers to Host/ENP rings	*/
extern CHAN	*data_chan;		/* Data channel array		*/

static
struct domain	*domains;


/*
 *	Define which protocols we want initialized (both host and ENP)
 *	and the channel allocations for them.
 */

static PIB	p_list[] = {
	{ PF_INET, SOCK_STREAM, 0, 20, "if_tcp" },
	{ PF_INET, SOCK_DGRAM, 20, 7, "if_udp" },
	{ PF_INET, SOCK_RAW, 27, 1, "if_rip" },
	{ PF_ETHER, SOCK_RAW, 28, 4, "if_eth" },
	{ 0, 0, 0, 0, 0, }
};


/*
 *	Local macros Etc.
 */

#define min(a,b) ((a)<(b)?(a):(b))
#define	TCPURGENT	0x40		/* HACK!! - so we don't include
					   net.h, internet.h, tcp.h !	*/


/*
 *	Locally declared external variables
 */

static SOCKET	sock_table[NSOCKETS];


/*
 *		The CMC Socket Device Driver
 */

so_open(dev, flags)
{
	register SOCKET *s;

	if (minor(dev) >= NSOCKETS) { 
		u.u_error = ENODEV;
		return;
	}

	if ((host.h_state & HS_INIT) == 0) {	/* ENP not inited	*/
		domaininit();		/* Set up protocol struct FIRST	*/
		init_enp(0, p_list);	/* Init ENP & protos we want	*/
	}

	s = &sock_table[(short) minor(dev)];

	if (s->so_state & (SS_RESV | SS_OPEN))
		u.u_error = EEXIST;
	else { 
		enp_zero(s, sizeof(SOCKET));
		s->so_state = SS_OPEN;
	}
}


so_close(dev)
{
	register SOCKET	*s;
	register CHAN	*cp;
	register BFR	*bp;
	register int	x;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_OPEN) == 0) { 
		u.u_error = EBADF;
		return;
	}

	if ((s->so_state & SS_RESV) == 0) {	/* No channel allocated	*/
		s->so_state = 0;
		return;
	}

	cp = &data_chan[(short) s->so_enpid];
	cp->c_state = htons(ntohs(cp->c_state) | SS_FLUSHING);

	(*s->so_proto->pr_close)(s);

	x = splnet();
	enpservice();
	splx(x);

	while ((bp = (BFR *) ringget(&cp->c_tohost))) {
		to_enp(enp->e_hostcomplete, bp);
		sringget(&cp->c_sring);
	}

	s->so_state = 0;			/* Free the socket	*/
}


so_read(dev)
{
	register SOCKET *s;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_CONNECTED) == 0) {
		u.u_error = EBADF;
		return;
	}

	sorecv(s, 0);
}


static
sorecv(s, flag)
register SOCKET *s;
{
	return (recvit(s, 0, 0, flag));
}


static
recvit(s, from, fromlen, flag)
register SOCKET	*s;
register char	*from;
register int	*fromlen;
{
	register BFR	*bp;
	register CHAN	*cp;
	register int	i, rcvd;
	register int	x;

	if (s->so_state & SS_NOREAD) {
		u.u_error = ESHUTDOWN;
		return (-1);
	}

	cp = (CHAN *) &data_chan[(short) s->so_enpid];

	i = splnet();
	enpservice();
	splx(i);

	rcvd = 0;
	while (u.u_count != 0) {
		i = splnet();
		while ((bp = (BFR *) fir(&cp->c_tohost)) == 0) {
			if ((rcvd) || (ntohs(cp->c_state) & SS_BROKEN)) {
				splx(i);
				return (rcvd);
			}
			if (u.u_fmode & FNDELAY) {
				u.u_error = EWOULDBLOCK;
				splx(i);
				return (-1);
			}
			sleep(&cp->c_tohost, PENP);
		}
		splx(i);

		if (i = min(bp->b_msglen, u.u_count)) {
			if (kern_to_user(bp->b_addr, u.u_base, i)) {
				u.u_error = EFAULT;
				return (-1);
			}
			if (from) {
				suword(fromlen, sizeof(sockaddr));
				if(kern_to_user((bp+1),from,sizeof(sockaddr))){
					u.u_error = EFAULT;
					return (-1);
				}
			}
			s->so_state &= ~SS_ATMARK;
			rcvd += i;
		}

		if ((bp->b_msglen -= i) == 0) {
			if (bp->b_flags & TCPURGENT) {	/* OOB	*/
				s->so_state |= SS_ATMARK;
				bp->b_flags &= ~TCPURGENT;
			}
			x = splnet();
			ringget(&cp->c_tohost);
			sringget(&cp->c_sring);
			splx(x);
			to_enp(enp->e_hostcomplete, bp);
			if (s->so_state & SS_ATMARK) {
				if (i == 0) {
					i = -1;
					u.u_error = EINTR;
				}
				return (i);
			}
		}
		else
			bp->b_addr += i;

		u.u_base += i;
		u.u_count -= i;
	}
	return (rcvd);
}


so_write(dev)
{
	register SOCKET *s;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_CONNECTED) == 0) {
		u.u_error = EBADF;
		return;
	}

	sosend(s, 0);
}


static
sosend(s, flag)
register SOCKET *s;
{
	register sockaddr	*to;

	to = (sockaddr *) (*s->so_proto->pr_send)(s);
	return (sendit(s, to, flag));
}


static
sendit(s, to, flag)
register SOCKET	*s;
register char	*to;
{
	register BFR	*bp;
	register PROTO	*pr;
	int		sent, i;

	if (s->so_state & SS_NOWRITE) {
		u.u_error = ESHUTDOWN;
		return (-1);
	}

	if (ntohs(data_chan[(short) s->so_enpid].c_state) & SS_BROKEN) {
		u.u_error = EPIPE;
		psignal(u.u_procp, SIGPIPE);
		return (-1);
	}

	i = splnet();
	enpservice();
	splx(i);

	pr = s->so_proto;

	sent = 0;
	while (u.u_count != 0) {
		if ((bp = (BFR *) get_buf(u.u_fmode & FNDELAY)) == 0) {
			u.u_error = EWOULDBLOCK;
			return (-1);
		}

		if (to)
			enp_move(to, bp->b_addr, sizeof(sockaddr));

		i = min(u.u_count, pr->pr_maxdata);
		if (user_to_kern(u.u_base, bp->b_addr + pr->pr_offset, i)) {
			fre_buf(bp);
			u.u_error = EFAULT;
			return (-1);
		}

		bp->b_flags = flag & MSG_OOB ? TCPURGENT : 0;
		bp->b_len = i;
		bp->b_device = s->so_enpid;
		to_enp(enp->h_tonet, bp);

		u.u_base += i;
		u.u_count -= i;
		sent += i;
	}
	return (sent);
}


/*
 *	The bulk of the work, and all of the socket-related 
 *	operations, takes place as a result of ioctl calls.
 */

so_ioctl(dev, cmd, arg, fflag)
{
	register SOCKET	*s, *s2;
	register CHAN	*cp;
	register int	i;

	in (   (  t		val;
	char		toname[SOCKNAMESIZE];
	short		NEEDCON, SOCKTYP, SOCKFAM;

	userparm	pblock, *pb;

	struct altblock {	/* alternate arg format used by ENP for RESV */
		long ab_af;
		long ab_type;
		long ab_proto;
	} altblock;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_OPEN) == 0) {
		u.u_error = EBADF;
		return;
	}

	/*	Set some "used a lot" test variables	*/

	NEEDCON = s->so_proto->pr_flags & PR_CONNREQUIRED;
	SOCKTYP = s->so_proto->pr_type;
	SOCKFAM = s->so_proto->pr_family;

	u.u_fmode = fflag;

	switch (cmd) {
	default:
		u.u_error = EOPNOTSUPP;
		break;

	case SIOCRESV:
		if (user_to_kern(arg, &altblock, sizeof(altblock))) {
			u.u_error = EFAULT;
			return;
		}
		if (so_resv(s, &altblock)) {
			s->so_pgrp = u.u_procp->p_pgrp;
			if ((fflag & FREAD) == 0)
				s->so_state |= SS_NOREAD;
			if ((fflag & FWRITE) == 0)
				s->so_state |= SS_NOWRITE;
		}
		break;

	case SIOCBIND:		/* bind a name to a socket */
		if (s->so_state & SS_BOUND) { 
			u.u_error = EINVAL;
			return;
		}
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		s->so_nmlen = min(pblock.p_len, SOCKNAMESIZE);
		if (user_to_kern(pblock.p_where, s->so_name, s->so_nmlen)) {
			u.u_error = EFAULT;
			return;
		}
		if (so_bind(s))
			s->so_state |= SS_BOUND;
		break;

	case SIOCGNAM:		/* get names associated with a socket */
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		so_gname(s, &pblock);
		break;

	case SIOCCONN:		/* connect to a remote socket */
		if (s->so_state & (SS_CONNECTED | SS_CONNECTING)) { 
			u.u_error = EISCONN;
			return;
		}
		if ((s->so_state & SS_BOUND) == 0) {
			if ((so_bind(s)) == 0)
				return;
			s->so_state |= SS_BOUND;
		}
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		i = min(pblock.p_len, SOCKNAMESIZE);
		if (user_to_kern(pblock.p_where, toname, i)) {
			u.u_error = EFAULT;
			return;
		}
		(*s->so_proto->pr_connect)(s, toname, 0, (fflag & FNDELAY));
		break;
	
	case SIOCACPT:
		if (SOCKTYP != SOCK_STREAM) {
			u.u_error = EOPNOTSUPP;
			return;
		}
		if ((s->so_state & SS_LISTEN) == 0) {
			u.u_error = EINVAL;
			return;
		}
		if ((arg = device(arg)) < 0) {
			u.u_error = EINVAL;
			return;
		}

		s2 = &sock_table[(short) minor(arg)];

		if ((s2->so_state & SS_OPEN) == 0) { 
			u.u_error = EBADF;
			return;
		}
		if ((s->so_state & SS_CONNECTING) == 0) {
			if ((s->so_state & SS_RESV) == 0) {
				if ((s->so_enpid = chan_alloc(s)) < 0) {
					u.u_error = ENOBUFS;
					return;
				}
				s->so_state |= SS_RESV;
			}
			(*s->so_proto->pr_connect)(s, 0, SS_LISTEN, 0);
		}
		if ((u.u_error = wait_for(s, (fflag & FNDELAY))) == 0) {
			*s2 = *s;
			s->so_state &= ~(SS_CONNECTED | SS_RESV);
		}
		break;

	case SIOCLISN:
		if (SOCKTYP != SOCK_STREAM) {
			u.u_error = EOPNOTSUPP;
			return;
		}
		if ((s->so_state & SS_BOUND) == 0) {
			u.u_error = EINVAL;
			return;
		}
		if (s->so_lim_listen == 0) { 
			if (arg < 0)
				arg = 1;
			s->so_lim_listen = min(arg, SOMAXCONN);
		}
		if ((s->so_state & SS_CONNECTING) == 0)
			(*s->so_proto->pr_connect)(s, 0, SS_LISTEN, 0);
		s->so_state |= SS_LISTEN;
		break;

	case SIOCSEND:
		if ((s->so_state & SS_BOUND) == 0) {
			u.u_error = EINVAL;
			return;
		}
		if ((NEEDCON) && ((s->so_state & SS_CONNECTED) == 0)) {
			u.u_error = EIO;
			return;
		}
		if (user_to_kern(arg, &pblock, sizeof (pblock))) {
			u.u_error = EFAULT;
			return;
		}
		pb = &pblock;
		u.u_base = pb->p_where;
		u.u_count = pb->p_len;
		i = sosend(s, pb->p_len2 & MSG_OOB);
		if (i > 0)
			u.u_rval1 = i;	/* return amount written */
		break;

	case SIOCSENDTO:
		if (s->so_state & SS_CONNECTED) {
			u.u_error = EISCONN;
			return;
		}
		if (user_to_kern(arg, &pblock, sizeof (pblock))) {
			u.u_error = EFAULT;
			return;
		}
		pb = &pblock;
		u.u_base = pb->p_where;
		u.u_count = pb->p_len;
		i = min(pb->p_len3, SOCKNAMESIZE);
		if (user_to_kern(pb->p_where3, toname, i)) {
			u.u_error = EFAULT;
			return;
		}
		i = sendit(s, toname, pb->p_len2 & MSG_OOB);
		if (i > 0)
			u.u_rval1 = i;	/* return amount written */
		break;

	case SIOCRECV:
		if ((s->so_state & SS_BOUND) == 0) {
			u.u_error = EINVAL;
			return;
		}
		if ((NEEDCON) && ((s->so_state & SS_CONNECTED) == 0)) {
			u.u_error = EIO;
			return;
		}
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		pb = &pblock;
		u.u_base = pb->p_where;
		u.u_count = pb->p_len;
		i = sorecv(s, pb->p_len2 & MSG_OOB);
		if (i > 0)
			u.u_rval1 = i;	/* return amount read */
		break;

	case SIOCRECVFROM:
		if ((s->so_state & SS_BOUND) == 0) {
			u.u_error = EINVAL;
			return;
		}
		if (s->so_state & SS_CONNECTED) {
			u.u_error = EISCONN;
			return;
		}
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		pb = &pblock;
		u.u_base = pb->p_where;
		u.u_count = pb->p_len;
		i = recvit(s, pb->p_where3, pb->p_len3, pb->p_len2 & MSG_OOB);
		if (i > 0)
			u.u_rval1 = i;	/* return amount read */
		break;

	case SIOCATMARK:
		i = s->so_state & SS_ATMARK ? 1 : 0;
		suword(arg, i);
		break;

	case SIOCSPGRP:
		i = fuword(arg);
		if (i != -1) {
			s->so_pgrp = i;
			if (s->so_state & SS_RESV) {
				cp = &data_chan[(short) s->so_enpid];
				cp->c_pgrp = i;
			}
		}
		else
			u.u_error = EFAULT;
		break;

	case SIOCGPGRP:
		suword(arg, s->so_pgrp);
		break;

	case SIOCSOPT:		/* set options */
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		s->so_options |= pblock.p_len2;
		if (s->so_state & SS_RESV) {
			cp = &data_chan[(short) s->so_enpid];
			cp->c_options = htons(ntohs(cp->c_options)|pblock.p_len2);
		}
		break;

	case SIOCGOPT:		/* get options */
		val = s->so_options;
		if (s->so_state & SS_RESV) {
			cp = &data_chan[(short) s->so_enpid];
			val |= ntohs(cp->c_options);
		}
		if (user_to_kern(arg, &pblock, sizeof(pblock))) {
			u.u_error = EFAULT;
			return;
		}
		suword(pblock.p_where, val);
		suword(pblock.p_len, sizeof(val));
		break;

	case SIOCSHUT:
		arg++;
		cp = &data_chan[(short) s->so_enpid];
		if (arg & 1) {
			s->so_state |= SS_NOREAD;
			cp->c_state = htons(ntohs(cp->c_state)|SS_FLUSHING);
		}
		if (arg & 2) {
			s->so_state |= SS_NOWRITE;
			so_close(dev);
		}
		break;
	}
}

#ifdef SELECT
so_select( dev, flag )
{
	register SOCKET *s;
	register CHAN   *cp;
	register struct proc *p;
	int x;
	extern	selwait;

	x = splnet();

	s = &sock_tab[ minor( dev ) ];
	cp = &data_chan[ s->so_enpid ];

	switch( flag ) {
	case FREAD:
		if ( fir ( &cp->c_tohost ) ) {
			splx( x );
			return ( 1 );
		}
		if ( (p = (struct proc *)cp->c_selproc)
					&& (p->p_wchan == (caddr_t) &selwait) )
			cp->c_state |= SS_SELCOLL;
		else
			cp->c_selproc = (caddr_t) u.u_procp;
		break;

	case FWRITE:
		if ( s->so_proto->pr_flags&PR_CONNREQUIRED )
			return( s->so_state&SS_CONNECTED );
		else {
			splx( x );
			return( 1 );
		}
		break;
	}

	splx( x );
	return( 0 );
}
#endif


typedef
struct PBLOCK {
	long	p_domain;		/* AF */
	long	p_type;			/* STREAM, DGRAM, etc */
	long	p_proto;		/* TCP, UDP, etc */
} PBLOCK;

static
so_resv(s, pb)
register SOCKET	*s;
register PBLOCK *pb;
{
	register PROTO	*pr;

	pr = (pb->p_proto) ? (PROTO *) pffindproto(pb->p_domain, pb->p_proto) :
			     (PROTO *) pffindtype(pb->p_domain, pb->p_type);

	if ((pr == 0) || (pb->p_type && (pr->pr_type != pb->p_type))) {
		u.u_error = ESOCKTNOSUPPORT;
		return (0);
	}
	else {
		s->so_proto = pr;
		if ((s->so_enpid = chan_alloc(s)) == -1) {
			u.u_error = ENOBUFS;
			return (0);
		}
		s->so_state |= SS_RESV;
		return (1);
	}
}


static
so_bind(s)
register SOCKET	*s;
{
	register PROTO	*pr = s->so_proto;

	if ((u.u_error = (*pr->pr_nmck)(s)) == 0) {
		if ((u.u_error = namecheck(pr, s->so_name, s->so_nmlen)) == 0)
			u.u_error = (*pr->pr_bind)(s);
	}

	return (u.u_error == 0);
}


static
so_gname(s, pb)
register SOCKET	*s;
register userparm *pb;
{
	register int	size;

	char		name[SOCKNAMESIZE];

	if ((size = (*s->so_proto->pr_gname)(s, name)) != 0) {
		if (pb->p_where)
			kern_to_user(name, pb->p_where, size);
		if (pb->p_len)
			suword(pb->p_len, size);
		if (pb->p_where2)
			kern_to_user(name+size, pb->p_where2, size);
		if (pb->p_len2)
			suword(pb->p_len2, size);
	}
}


wait_for(s, dontwait)
register SOCKET	*s;
{
	register BFR	*bp;
	register OPN	*op;
	register CHAN	*cp;
	register int	x;

	op = s->so_o_opn;
	bp = s->so_o_bfr;

	x = splnet();
	while (op->o_status == -1) {
		if (dontwait) {
			splx(x);
			return (EWOULDBLOCK);
		}
		sleep(bp, PENP);
	}
	splx(x);
	x = ntohs(op->o_status);

	s->so_state &= ~SS_CONNECTING;
	s->so_o_bfr = 0;
	s->so_o_opn = 0;
	fre_buf(bp);

	if (x == 0)
		s->so_state |= SS_CONNECTED;

#ifdef SELECT
	cp = &data_chan[(short) s->so_enpid];
	if (cp->c_selproc) {
		selwakeup(cp->c_selproc, ntohs(cp->c_state)&SS_SELCOLL);
		cp->c_selproc = 0;
		cp->c_state = htons(ntohs(cp->c_state) & ~SS_SELCOLL);
	}
#endif
	return (x);
}


static
chan_alloc(s)
register SOCKET	*s;
{
	register PROTO	*pr = s->so_proto;
	register CHAN	*cp;
	register short	i;

	for (i = pr->pr_next; i < pr->pr_end; i++)
	if (data_chan[i].c_state == SS_AVAIL)
		goto found;

	for (i = pr->pr_channel; i <= pr->pr_next; i++)
	if (data_chan[i].c_state == SS_AVAIL)
		goto found;

	return (-1);

found:
	cp = &data_chan[i];
	cp->c_state = htons(SS_ALLOC);
	cp->c_selproc = 0;
	cp->c_pgrp = s->so_pgrp;
	cp->c_options = htons(s->so_options);

	pr->pr_next = i + 1;
	if (pr->pr_next == pr->pr_end)
		pr->pr_next = pr->pr_channel;

	return (i);
}


#define	ADDDOMAIN(x)	{ \
	extern struct domain x/**/domain; \
	x/**/domain.dom_next = domains; \
	domains = &x/**/domain; \
}

static
domaininit()
{
#ifndef lint
	ADDDOMAIN(inet);
	ADDDOMAIN(eth);
#endif lint
}


pffindtype(family, type)
int	family, type;
{
	register struct domain *dp;
	register struct protosw *pr;

	for (dp = domains; dp; dp = dp->dom_next)
		if (dp->dom_family == family)
			goto found;
	return (0);
found:
	for (pr = dp->domps; pr < dp->domps_END; pr++)
		if (pr->pr_type && pr->pr_type == type)
			return ((int)pr);
	return (0);
}

pffindproto(family, protocol)
int	family, protocol;
{
	register struct domain *dp;
	register struct protosw *pr;

	if (family == 0)
		return (0);
	for (dp  (   (  = domains; dp; dp = dp->dom_next)
		if (dp->dom_family == family)
			goto found;
	return (0);
found:
	for (pr = dp->domps; pr < dp->domps_END; pr++)
		if (pr->pr_protocol == protocol)
			return ((int)pr);
	return (0);
}

namecheck(proto, nm, nmlen)
register PROTO	*proto;
caddr_t		nm;
{
	register SOCKET	*s;
	register	res;

	for (s = &sock_table[0]; s < &sock_table[NSOCKETS]; s++) {
		if ((s->so_proto == proto) && (s->so_state&SS_BOUND)) {
			res = (*proto->pr_cmp) (s->so_name, nm, nmlen,
				s->so_options & SO_REUSEADDR);
			if (res)
				return (res);
		}
	}
	return (0);
}
eak;

	case SIOCRESV:
		if (user_to_kern(arg, &altblock, sizeof(altblock))) {
			u.u_error = EFAULT;
			return;
		}
		if (so_resv(s, &altblock)) {
			s->so_pgrp = u.u_procp->p_pgrp;
			if ((fflag & FREAD) == 0)
				s->so_state |= SS_NOREAD;
			if ((fflag & FWRITE) == 0)
				s->so_state |= SS_NOWRITE;
		}
		break;

	case SIOCBIND:		/* bind a name to a socket */
		if (s->so_state & SS_BOUND) { 
			u.u_error = EINVAL;
			return;
		}
		if (user_unix/sys/tags                                                                                          664       0     145         6741  4031527356   6560                                                                                                                                                                                                                                                                                                                                                                      ADDDOMAIN	sock_driver.c	/^#define	ADDDOMAIN(x)	{ \\$/
chan_alloc	sock_driver.c	/^chan_alloc(s)$/
device	enp10.c	/^device(fid)$/
domaininit	sock_driver.c	/^domaininit()$/
enp_move	enp.c	/^enp_move(src, dest, cnt)$/
enp_zero	enp.c	/^enp_zero(dest, cnt)$/
enpbfr	enp.c	/^enpbfr(bp)$/
enpgo	enp10.c	/^enpgo(enpaddr, arg)$/
enpintr	enp10.c	/^enpintr()$/
enprclose	enpram.c	/^enprclose()$/
enprioctl	enpram.c	/^enprioctl(dev, cmd, arg, mode)$/
enpropen	enpram.c	/^enpropen()$/
enprread	enpram.c	/^enprread()$/
enprwrite	enpram.c	/^enprwrite()$/
enpservice	enp.c	/^enpservice()$/
eth_cmp	eth_proto.c	/^eth_cmp(inp1, inp2, len, reuse)$/
ethbind	if_eth.c	/^ethbind(s)$/
ethclose	if_eth.c	/^ethclose(s)$/
ethconnect	if_eth.c	/^ethconnect(s, to, type, flags)$/
ethgname	eth_proto.c	/^ethgname(s, place)$/
ethnmchk	eth_proto.c	/^ethnmchk(s)$/
ethrecv	if_eth.c	/^ethrecv(s)$/
ethsend	if_eth.c	/^ethsend(s)$/
fir	ring.c	/^fir( rp )$/
fre_buf	enp.c	/^fre_buf(bp)$/
get_buf	enp.c	/^get_buf(dontwait)$/
hostbfr	enp.c	/^hostbfr(bp)$/
init_enp	enp.c	/^init_enp(pass, pb)$/
intenp	enp10.c	/^intenp()$/
ip_cmp	in_proto.c	/^ip_cmp(inp1, inp2, len, reuse)$/
ipgname	in_proto.c	/^ipgname(s, place)$/
ipnmchk	in_proto.c	/^ipnmchk(s)$/
kern_to_user	enp10.c	/^kern_to_user(from, to, count)$/
min	sock_driver.c	/^#define min(a,b) ((a)<(b)?(a):(b))$/
namecheck	sock_driver.c	/^namecheck(proto, nm, nmlen)$/
pffindproto	sock_driver.c	/^pffindproto(family, protocol)$/
pffindtype	sock_driver.c	/^pffindtype(family, type)$/
ptcclose	pty.c	/^ptcclose (dev)$/
ptcioctl	pty.c	/^ptcioctl (dev, cmd, arg, mode)$/
ptcopen	pty.c	/^ptcopen (dev, flag)$/
ptcread	pty.c	/^ptcread (dev)$/
ptcselect	pty.c	/^ptcselect()$/
ptcwrite	pty.c	/^ptcwrite (dev)$/
ptsclose	pty.c	/^ptsclose (dev)$/
ptsioctl	pty.c	/^ptsioctl (dev, cmd, arg, mode)$/
ptsopen	pty.c	/^ptsopen (dev, flag)$/
ptsread	pty.c	/^ptsread (dev)			\/* normally never called *\/$/
ptswrite	pty.c	/^ptswrite (dev)			\/* normally never called *\/$/
ptyproc	pty.c	/^ptyproc (tp, cmd)$/
recvit	sock_driver.c	/^recvit(s, from, fromlen, flag)$/
resetenp	enp10.c	/^resetenp(enpaddr)$/
ringempty	ring.c	/^ringempty( rp )$/
ringfull	ring.c	/^ringfull( rp )$/
ringget	ring.c	/^ringget( rp )$/
ringinit	ring.c	/^ringinit( rp,size )$/
ringput	ring.c	/^ringput( rp,v )$/
ripbind	if_rip.c	/^ripbind(s)$/
ripclose	if_rip.c	/^ripclose(s)$/
ripconnect	if_rip.c	/^ripconnect(s, to, type, flags)$/
ripnmchk	if_rip.c	/^ripnmchk(s)$/
riprecv	if_rip.c	/^riprecv(s)$/
ripsend	if_rip.c	/^ripsend(s)$/
sendit	sock_driver.c	/^sendit(s, to, flag)$/
so_bind	sock_driver.c	/^so_bind(s)$/
so_close	sock_driver.c	/^so_close(dev)$/
so_gname	sock_driver.c	/^so_gname(s, pb)$/
so_ioctl	sock_driver.c	/^so_ioctl(dev, cmd, arg, fflag)$/
so_open	sock_driver.c	/^so_open(dev, flags)$/
so_read	sock_driver.c	/^so_read(dev)$/
so_resv	sock_driver.c	/^so_resv(s, pb)$/
so_select	sock_driver.c	/^so_select( dev, flag )$/
so_write	sock_driver.c	/^so_write(dev)$/
sorecv	sock_driver.c	/^sorecv(s, flag)$/
sosend	sock_driver.c	/^sosend(s, flag)$/
splnet	enp10.c	/^splnet()$/
tcpbind	if_tcp.c	/^tcpbind(s)$/
tcpclose	if_tcp.c	/^tcpclose(s)$/
tcpconnect	if_tcp.c	/^tcpconnect(s, to, type, flags)$/
tcprecv	if_tcp.c	/^tcprecv(s)$/
tcpsend	if_tcp.c	/^tcpsend(s)$/
to_enp	enp.c	/^to_enp(rp, bp)$/
udpbind	if_udp.c	/^udpbind(s)$/
udpclose	if_udp.c	/^udpclose(s)$/
udpconnect	if_udp.c	/^udpconnect(s, to, type, flags)$/
udprecv	if_udp.c	/^udprecv(s)$/
udpsend	if_udp.c	/^udpsend(s)$/
user_to_kern	enp10.c	/^user_to_kern(from, to , count)$/
wait_for	sock_driver.c	/^wait_for(s, dontwait)$/
>p_len2 & MSG_OOB);
		if (i > 0                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ;	/* Init ENP & protos we want	*/
	}

	s = &sock_table[(short) minor(dev)];

	if (s->so_state & (SS_RESV | SS_OPEN))
		u.u_error = EEXIST;
	else { 
		enp_zero(s, sizeof(SOCKET));
		s->so_state = SS_OPEN;
	}
}


so_close(dev)
{
	register SOCKET	*s;
	register CHAN	*cp;
	register BFR	*bp;
	register int	x;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_OPEN) == 0) { 
		u.u_error = EBADF;
		return;
	}

	if ((s->so_state & SS_RESV) == 0) {	/* No channel allocated	*/
		s->so_state = 0;
		return;
	}

	cp = &data_chan[(short) s->so_enpid];
	cp->c_state = htons(ntohs(cp->c_state) | SS_FLUSHING);

	(*s->so_proto->pr_close)(s);

	x = splnet();
	enpservice();
	splx(x);

	while ((bp = (BFR *) ringget(&cp->c_tohost))) {
		to_enp(enp->e_hostcomplete, bp);
		sringget(&cp->c_sring);
	}

	s->so_state = 0;			/* Free the socket	*/
}


so_read(dev)
{
	register SOCKET *s;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_CONNECTED) == 0) {
		u.u_error = EBADF;
		return;
	}

	sorecv(s, 0);
}


static
sorecv(s, flag)
register SOCKET *s;
{
	return (recvit(s, 0, 0, flag));
}


static
recvit(s, from, fromlen, flag)
register SOCKET	*s;
register char	*from;
register int	*fromlen;
{
	register BFR	*bp;
	register CHAN	*cp;
	register int	i, rcvd;
	register int	x;

	if (s->so_state & SS_NOREAD) {
		u.u_error = ESHUTDOWN;
		return (-1);
	}

	cp = (CHAN *) &data_chan[(short) s->so_enpid];

	i = splnet();
	enpservice();
	splx(i);

	rcvd = 0;
	while (u.u_count != 0) {
		i = splnet();
		while ((bp = (BFR *) fir(&cp->c_tohost)) == 0) {
			if ((rcvd) || (ntohs(cp->c_state) & SS_BROKEN)) {
				splx(i);
				return (rcvd);
			}
			if (u.u_fmode & FNDELAY) {
				u.u_error = EWOULDBLOCK;
				splx(i);
				return (-1);
			}
			sleep(&cp->c_tohost, PENP);
		}
		splx(i);

		if (i = min(bp->b_msglen, u.u_count)) {
			if (kern_to_user(bp->b_addr, u.u_base, i)) {
				u.u_error = EFAULT;
				return (-1);
			}
			if (from) {
				suword(fromlen, sizeof(sockaddr));
				if(kern_to_user((bp+1),from,sizeof(sockaddr))){
					u.u_error = EFAULT;
					return (-1);
				}
			}
			s->so_state &= ~SS_ATMARK;
			rcvd += i;
		}

		if ((bp->b_msglen -= i) == 0) {
			if (bp->b_flags & TCPURGENT) {	/* OOB	*/
				s->so_state |= SS_ATMARK;
				bp->b_flags &= ~TCPURGENT;
			}
			x = splnet();
			ringget(&cp->c_tohost);
			sringget(&cp->c_sring);
			splx(x);
			to_enp(enp->e_hostcomplete, bp);
			if (s->so_state & SS_ATMARK) {
				if (i == 0) {
					i = -1;
					u.u_error = EINTR;
				}
				return (i);
			}
		}
		else
			bp->b_addr += i;

		u.u_base += i;
		u.u_count -= i;
	}
	return (rcvd);
}


so_write(dev)
{
	register SOCKET *s;

	s = &sock_table[(short) minor(dev)];

	if ((s->so_state & SS_CONNECTED) == 0) {
		u.u_error = EBADF;
		return;
	}

	sosend(s, 0);
}


static
sosend(s, flag)
register SOCKET *s;
{
	register sockaddr	*to;

	to = (sockaddr *) (*s->so_proto->pr_send)(s);
	return (sendit(s, to, flag));
}


static
sendit(s, to, flag)
register SOCKET	*s;
register char	*to;
{
	register BFR	*bp;
	register PROTO	*pr;
	int		sent, i;

	if (s->so_state & SS_NOWRITE) {
		u.u_error = ESHUTDOWN;
		return (-1);
	}

	if (ntohs(data_chan[(short) s->so_enpid].c_state) & SS_BROKEN) {
		u.u_error = EPIPE;
		psignal(u.u_procp, SIGPIPE);
		return (-1);
	}

	i = splnet();
	enpservice();
	splx(i);

	pr = s->so_proto;

	sent = 0;
	while (u.u_count != 0) {
		if ((bp = (BFR *) get_buf(u.u_fmode & FNDELAY)) == 0) {
			u.u_error = EWOULDBLOCK;
			return (-1);
		}

		if (to)
			enp_move(to, bp->b_addr, sizeof(sockaddr));

		i = min(u.u_count, pr->pr_maxdata);
		if (user_to_kern(u.u_base, bp->b_addr + pr->pr_offset, i)) {
			fre_buf(bp);
			u.u_error = EFAULT;
			return (-1);
		}

		bp->b_flags = flag & MSG_OOB ? TCPURGENT : 0;
		bp->b_len = i;
		bp->b_device = s->so_enpid;
		to_enp(enp->h_tonet, bp);

		u.u_base += i;
		u.u_count -= i;
		sent += i;
	}
	return (sent);
}


/*
 *	The bulk of the work, and all of the socket-related 
 *	operations, takes place as a result of ioctl calls.
 */

so_ioctl(dev, cmd, arg, fflag)
{
	register SOCKET	*s, *s2;
	register CHAN	*cp;
	register int	i;

	in (          