[comp.sources.d] callback source

klein@mechp10.UUCP (Greg Klein) (05/10/89)

About a month ago I posted a request for getty and login source code that
I could use to write a callback program.  Here's what I came up with.

You get a login and password prompt as usual and then the system disconnects
your line and calls you back at your remote phone number (in your .cbtelno
file).  Your modem answers the call and you are then prompted for a normal
login.

There are two programs, gettycb and logincb.  gettycb is started
by init from an /etc/inittab entry just like getty and gettycb invokes
logincb after a user name is entered.  Since gettycb is functionally
equivalent to getty except that it invokes logincb instead of login, I could
have simply not bothered with gettycb at all and just replaced /bin/login
with the callback version.  However, I needed to retain login for regular
non-callback) logins.  The man pages should be adequate documentation.

I'm running this on a HP 350 under HP-UX (an AT&T/Berkley UNIX merge).  I 
haven't tried it on any other configuration.

I WAS able to get PD login and getty source code, but not until after I
finished writing the callback program, so I didn't use the source.

It's a bit dirty but it works for me.  Feel free to email me any improvements.

=========================================================================
Greg Klein				| Microcomputer Electronics Corp.
voice:	(206)821-2800 x702		| 12421 Willows Rd, NE
uucp:	...!hplabs!hpubvwa!mechp!klein	| Kirkland WA, USA 98034
=========================================================================


# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Greg Klein <klein@mechp10> on Tue May  9 12:52:55 1989
#
# This archive contains:
#	mk.gettycb	mk.logincb	gettycb.1	logincb.1	
#	gettycb.c	logincb.c	
#

LANG=""; export LANG

echo x - mk.gettycb
cat >mk.gettycb <<'@EOF'
CFLAGS =	-O

gettycb:
@EOF

chmod 644 mk.gettycb

echo x - mk.logincb
cat >mk.logincb <<'@EOF'
CFLAGS =	-O

logincb:
@EOF

chmod 644 mk.logincb


rm -f /tmp/uud$$
(echo "begin 777 /tmp/uud$$\n \nend" | uudecode) >/dev/null 2>&1
if [ -f /tmp/uud$$ ]
then
	rm -f /tmp/uud$$
	unpacker=uudecode
else
	echo Compiling unpacker for non-ascii files
	pwd=`pwd`; cd /tmp
	cat >unpack$$.c <<-'EOF'
	#include <stdio.h>
	#define DEC(c)	(((c) - ' ') & 077)
	main()
	{
		int n;
		char dest[128], a,b,c,d;

		scanf("begin %o ", &n);
		gets(dest);

		if (freopen(dest, "w", stdout) == NULL) {
			perror(dest);
			exit(1);
		}

		while ((n=getchar()) != EOF && (n=DEC(n))!=0)  {
			while (n>0) {
				a = DEC(getchar());
				b = DEC(getchar());
				c = DEC(getchar());
				d = DEC(getchar());
				if (n-- > 0) putchar(a << 2 | b >> 4);
				if (n-- > 0) putchar(b << 4 | c >> 2);
				if (n-- > 0) putchar(c << 6 | d);
			}
			n=getchar();
		}
		exit(0);
	}
	EOF
	cc -o unpack$$ unpack$$.c
	rm unpack$$.c
	cd $pwd
	unpacker=/tmp/unpack$$
fi

echo x - gettycb.1 '[non-ascii]'
$unpacker <<'@eof'
begin 644 gettycb.1
M+F1E?48@(" @(" @(" @(" @(" @(" @(" @(" @(" @("!<(B!R961E9FEN
M92!F;V]T97(@;6%C<F\@9F]R($U%0PHN9',I2"!,;V-A; HN978Q"BY]10HN
M:69<7&XH*7,@)W-P('Q<7&XH+G!U+3%V+3%P"BYI9EQ<;B@I=" G<W @?%Q<
M;B@N<'4M,W8*+FEF;B G<W @?%Q<;B@N<'4M-'8*+G1L!UQ<*B@I2 <M("4@
M+0=<7"HH75<'"B=B< HN978*+BX*+FYR("E,(#8S=B @(" @(" @(" @(" @
M(" @(" @(" @("!<(B!S970@<&%G92!L96YG=&@@9F]R(&1E8R!L87-E<@HN
M5$@@1T545%E#0B Q("),;V-A;"(*+E5#(#0*+E-(($Y!344*9V5T='EC8B!<
M+2!S970@=&5R;6EN86P@='EP92P@;6]D97,L('-P965D+"!A;F0@;&EN92!D
M:7-C:7!L:6YE(&9O<B!C86QL(&)A8VL*+E-((%-93D]04TE3"B]U<W(O;&]C
M86PO971C+V=E='1Y8V(@6RUD;%T@6RUT('1I;65O=71=(&QI;F4@6W-P965D
M70HN4T@@1$530U))4%1)3TX*1V5T='EC8B!I<R!A('!R;V=R86T@=&AA="!I
M<R!I;G9O:V5D(&)Y(&EN:70H,4TI+B @270@:7,@:6YT96YD960@=&\@8F4*
M:G5S="!L:6ME(&=E='1Y*#$I(&5X8V5P="!T:&%T(&EN<W1E860@;V8@97AE
M8R=I;F<@*&5X96,H,BDI(&QO9VEN*#$I(&%F=&5R('1H90IU<V5R(&QO9W,@
M:6XL(&QO9VEN8V(H,2D@:7,@97AE8R=E9"X@($QO9VEN8V(@=&AE;B!C86QL
M<R!B86-K('1H92!U<V5R"F]N(&%N(&%V86EL86)L92!C86QL;W5T(&QI;F4@
M86YD('-P87=N<R!G971T>2!O;B!T:&%T(&QI;F4@<V\@=&AA="!T:&4*=7-E
M<B!M87D@;&]G(&EN('=H96X@=&AE(&-A;&P@8F%C:R!I<R!A;G-W97)E9"!B
M>2!T:&4@=7-E<B=S(&UO9&5M+B @1V5T='EC8@IA;F0@;&]G:6YC8B!T:'5S
M('!R;W9I9&4@82!S96-U<F4@<F5M;W1E(&QO9VEN('1O('1H92!S>7-T96TN
M"BY0"DYO<FUA;&QY+"!T:&5R92!N965D(&YO="!B92!M;W)E('1H86X@;VYE
M(&EN<W1A;F-E(&]F(&=E='1Y8V(@<G5N;FEN9R!O;B!A"G-Y<W1E;2 H86QT
M:&]U9V@@=&AE<F4@8V%N(&)E*2X@(%1H870@:7,L(&]N;'D@;VYE(&QI;F4@
M:7,@=7-E9"!T;R!A;G-W97(*8V%L;',N("!4:&4*+V5T8R]I;FET=&%B(&9I
M;&4@=V]U;&0@=&AE;B!C;VYT86EN('1H92!S:6YG;&4@9V5T='EC8B!E;G1R
M>2!S=6-H(&%S.@HB9S(Z,CIR97-P87=N.B]U<W(O;&]C86PO971C+V=E='1Y
M8V(@+70@,S @='1Y,#0@,3(P,"XB("!/;F-E(&=E='1Y8V(*86YS=V5R<R!A
M(&-A;&PL(&ET(&5X96,G<R!L;V=I;F-B('=H:6-H(&-A;&QS(&)A8VL@;VX@
M=&AE(&9I<G-T(&%V86EL86)L90IC86QL;W5T(&1E=FEC92!I="!F:6YD<R!I
M;B!T:&4@3"U$979I8V5S(&9I;&4@*&]R($1E=FEC97,@9FEL92!F;W(@2$1"
M('5U8W I+@I)9B!T:&4@8V%L;"UI;B!L:6YE("AE>&%M<&QE('1T>3 T(&ES
M(&%L<V\@=7-E9"!A<R!A(&-A;&PM;W5T(&QI;F4@*&5X86UP;&4*8W5L,#0I
M('1H96X@=&AA="!C86QL+6]U="!L:6YE('-H;W5L9"!B92!T:&4@;&%S="!O
M;F4@;&ES=&5D(&EN('1H92!,+41E=FEC97,*9FEL92!S;R!T:&%T('1H92!O
M;F4@8V%L;"UI;B!L:6YE('=I;&P@<F5M86EN(&%V86EL86)L92!T;R!A;G-W
M97(@8V%L;',@=6YT:6P*:70@:7,@86QS;R!F:6YA;&QY(&-H;W-E;B!T;R!C
M86QL(&)A8VL@;VXN"BY0"DQO9VEN8V(@86-T=6%L;'D@<W!A=VYS(&$@9&EF
M9F5R96YT('!R;V-E<W,@=&\@<&5R9F]R;2!T:&4@8V%L;"!B86-K(&%N9"!T
M:&5N"FET(&5X:71S(&-A=7-I;F<@9V5T='EC8B!T;R!R97-P87=N(&EF(")R
M97-P87=N(B!I<R!S<&5C:69I960@:6X@=&AE(&EN:71T86(*96YT<GD@87,@
M:6X@=&AE(&5X86UP;&4@86)O=F4N("!">2!R97-P87=N:6YG(&=E='1Y8V(L
M(&%D9&ET:6]N86P@8V%L;',*8V%N(&)E(&%N<W=E<F5D+@HN4 I3:6YC92!A
M(&-A;&P@8F%C:R!C86X@;V-C=7(@;W9E<B!T:&4@<V%M92!L:6YE('1H870@
M9V5T='EC8B!I<R!A;')E861Y"G)U;FYI;F<@*')E<W!A=VYE9"D@;VXL(&ET
M(&ES(&EM<&]R=&%N="!T:&%T(&%L;"!L:6YE<R H97@N('1T>3 T*0IU<V5D
M('=I=&@@9V5T='EC8B!B92!C<F5A=&5D("AU<VEN9R!M:VYO9"@Q32DI(&%S
M("=C86QL+6EN)R!D979I8V5S(&%N9"!A;&P@"FQI;F5S('5S960@9F]R(&-A
M;&P@8F%C:R H;&EN97,@:6X@=&AE($PM1&5V:6-E<R!F:6QE*0IB92!C<F5A
M=&5D(&%S("=C86QL+6]U="<@9&5V:6-E<RX@(%1H:7,@<')O=FED97,@9F]R
M(&-O<G)E8W0@=&5R;6EN86P*<&]R="!A8V-E<W,@:6YT97)L;V-K("AR969E
M<B!T;R!M;V1E;2@W*2DN"BY0"DEN:71I86QL>2P@:68@+V5T8R]I<W-U92!E
M>&ES=',L(&=E='1Y8V(@<')I;G1S(&ET<R!C;VYT96YT<R!T;R!T:&4@=7-E
M<B=S"G1E<FUI;F%L+"!F;VQL;W=E9"!B>2!T:&4@<')O;7!T(")L;V=I;CH@
M(BX@($=E='1Y8V(@<F5A9',@=&AE('5S97(G<R!L;V=I;@IN86UE(&%N9"!I
M;G9O:V5S(&QO9VEN8V(@=VET:"!T:&4@=7-E<B=S(&YA;64@87,@87)G=6UE
M;G0N("!7:&EL92!R96%D:6YG"G1H92!N86UE+"!G971T>2!A='1E;7!T<R!T
M;R!A9&%P="!T:&4@<WES=&5M('1O('1H92!S<&5E9"!O9B!T:&4@=&5R;6EN
M86P*8F5I;F<@=7-E9"X*+E *3&EN92!I<R!T:&4@;F%M92!O9B!T:&4@='1Y
M(&QI;F4@:6X@+V1E=B!T;R!W:&EC:"!G971T>6-B(&ES('1O(&%T=&%C:"!I
M='-E;&8N"D=E='1Y8V(@=7-E<R!T:&ES('-T<FEN9R!A<R!T:&4@;F%M92!O
M9B!A(&9I;&4@:6X@=&AE("]D978@9&ER96-T;W)Y('1O(&]P96X*9F]R(')E
M861I;F<@86YD('=R:71I;F<N("!4:&4@+70@9FQA9R!P;'5S('1I;65O=70@
M:6X@<V5C;VYD<RP@<W!E8VEF:65S('1H870*9V5T='EC8B!S:&]U;&0@97AI
M="!I9B!T:&4@;W!E;B!O;B!T:&4@;&EN92!S=6-C965D<R!A;F0@;F\@;VYE
M('1Y<&5S( IA;GET:&EN9R!I;B!T:&4@<W!E8VEF:65D(&YU;6)E<B!O9B!S
M96-O;F1S+B @5&AE(&]P=&EO;F%L('-E8V]N9"!A<F=U;65N="P*<W!E960L
M('1E;&QS(&=E='1Y8V(@=VAA="!S<&5E9"!T;R!I;FET:6%L;'D@<G5N+B @
M5&AE(&]N;'D@=F%L:60@<W!E961S"F%R92 S,# L(#$R,# L(&%N9" R-# P
M+B @5&AE(&1E9F%U;'0@<W!E960@:7,@,S P(&)A=60N("!4:&4@+6P@9FQA
M9R!T=7)N<R!O;@IL;V=G:6YG('1O('1H92!F:6QE("]U<W(O861M+V-B;&]G
M+B @06X@96YT<GD@:7,@87!P96YD960@=&\@=&AI<R!F:6QE(&5A8V@*=&EM
M92!J=7-T(&)E9F]R92!S<&%W;FEN9R!L;V=I;F-B+B @5&AE("UD(&9L86<@
M='5R;G,@;VX@9&5B=6=G:6YG('1O('1H92!F:6QE"B]T;7 O9V5T='EC8BYD
M8F<N("!687)I;W5S(&EN9F]R;6%T:6]N('-U8V@@87,@96%C:"!C:&%R86-T
M97(@<F5C96EV960@9G)O;0IA('5S97(@:7,@87!P96YD960@=&\@=&AI<R!F
M:6QE+@HN4 I!9G1E<B!T:&4@;&EN92!I<R!O<&5N960L(&ET(&ES('-E="!T
M;R!R87<@;6]D92 H<F5A9"!A=V%K96YS(&]N(&5V97)Y"F-H87)A8W1E<BDL
M(&5C:&\@:7,@<W5P<')E<W-E9"P@96ET:&5R('!A<FET>2!I<R!A;&QO=V5D
M(&]N(&EN<'5T+"!E=F5N('!A<FET>0IO=71P=70L(&-A<G)I86=E(')E='5R
M;B!I<R!C;VYV97)T960@=&\@;F5W+6QI;F4@;VX@:6YP=70L(&%N9"!O=71P
M=70@;F5W+6QI;F4*8VAA<F%C=&5R<R!A<F4@8V]N=F5R=&5D('1O(&-A<G)I
M86=E(')E='5R;BUL:6YE(&9E960N"DET('1Y<&5S('1H92!L;V=I;B!M97-S
M86=E(&)E9F]R92!R96%D:6YG('1H92!U<V5R)W,@;F%M92!A(&-H87)A8W1E
M<B!A= IA('1I;64N("!)9B!A(&YU;&P@8VAA<F%C=&5R("AO<B!F<F%M:6YG
M(&5R<F]R*2!I<R!R96-E:79E9"P@:70@:7,@87-S=6UE9"!T;PIB92!T:&4@
M<F5S=6QT(&]F('1H92!U<V5R('!U<VAI;F<@=&AE(&!@8G)E86LG)R!K97DN
M("!4:&ES('=I;&P@8V%U<V4@9V5T='EC8@IT;R!A='1E;7!T('1H92!N97AT
M('-P965D(&EN('1H92!S97)I97,@;V8@,S P+3XQ,C P+3XR-# P+3XS,# M
M/B!E=&,N"BY0"E1H92!U<V5R)W,@;F%M92!I<R!T97)M:6YA=&5D(&)Y(&$@
M8V%R<FEA9V4M<F5T=7)N+@HN4 I4:&4@<WEM8F]L<R C(&%N9"! (&%R92!R
M96-O9VYI>F5D(&%S(&-H87)A8W1E<B!E<F%S92!A;F0@;&EN92!K:6QL"F-H
M87)A8W1E<G,L(')E<W!E8W1I=F5L>2X*+E-(($9)3$53"B]U<W(O;&]C86PO
M971C+V=E='1Y8V(*+F)R"B]E=&,O:7-S=64*+F)R"B]U<W(O861M+V-B;&]G
M"BYB<@HO=&UP+V=E='1Y8V(N9&)G"BYB<@HO=7-R+VQI8B]U=6-P+TPM1&5V
M:6-E<PHN4T@@4T5%($%,4T\*8W0H,2DL(&EN:70H,4TI+"!L;V=I;B@Q*2P@
M;&]G:6YC8B@Q*2P@9V5T='DH,2DL(&=E='1Y9&5F<R@T*2P@:6YI='1A8B@T
M*2P*;6]D96TH-RDL('1E<FUI;R@W*2X*+E-((%=!4DY)3D=3"D-O;7!A<FEN
M9R!T:&4@86)O=F4@9&5S8W)I<'1I;VX@;V8@9V5T='EC8B!A;F0@=&AA="!O
M9B!G971T>2P@;VYE('=I;&P@9FEN9 IA(&YU;6)E<B!O9B!D:69F97)E;F-E
M<RP@;6]S="!O9B!T:&4@9&EF9F5R96YC97,@87)E(&9E871U<F5S(&]F(&=E
M='1Y('1H870*=V5R92!O;6ET=&5D(&EN(&=E='1Y8V(@:6X@=&AE(&EN=&5R
M97-T(&]F('-I;7!L:6-I='D@*'1H92!S;W5R8V4@8V]D92!F;W(*9V5T='D@
M=V%S(&YO="!A=F%I;&%B;&4I+B @5&AE('!R:6UA<GD@9&EF9F5R96YC97,@
M8F5T=V5E;B!G971T>6-B(&%N9 IG971T>2!A<F4@87,@9F]L;&]W<SH*+E)3
M"BY44" U"C$N"D=E='1Y8V(@<W!A=VYS(&QO9VEN8V(@:6YS=&5A9"!O9B!L
M;V=I;BX*+E10"C(N"E1H92 M:"!O<'1I;VX@;V8@9V5T='D@:7,@;F]T('-U
M<'!O<G1E9"X@($=E='1Y8V(@9&]E<R!N;W0@9F]R8V4@82!H86YG=7 @;VX*
M=&AE(&QI;F4@8F5F;W)E('-E='1I;F<@=&AE(&QI;F4@=&\@=&AE('!R;W!E
M<B!S<&5E9"X*+E10"C,N"D]N;'D@=&AE('9A;'5E<R!O9B S,# L(#$R,# L
M(&%N9" R-# P(&9O<B G<W!E960G(&%R92!V86QI9"X*+E10"C0N"E1H92!F
M:6QE("]E=&,O9V5T='ED969S(&ES('5S960@8GD@9V5T='D@=&\@<W!E8VEF
M>2!C97)T86EN('!R;V=R86UM86)L92 *8VAA<F%C=&5R:7-T:6-S(&)U="!T
M:&ES(&9I;&4@:7,@;F]T('5S960@8GD@9V5T='EC8BX*+E10"C4N"E1H92 G
M='EP92<@86YD("=L:6YE9&ES8R<@;W!T:6]N<R!O9B!G971T>2!A<F4@;F]T
M('-U<'!O<G1E9"X*+E10"C8N"E1H92 M;"!A;F0@+60@;W!T:6]N<R!O9B!G
M971T>6-B(&%R92!N;W0@<W5P<&]R=&5D(&)Y(&=E='1Y+@HN4T@@0E5'4PI)
M="!I<R!N;W0@<&]S<VEB;&4@=&\@;&]G:6X@=FEA(&=E='1Y8V(@86YD('1Y
M<&4@(R!O<B! (&%S('!A<G0@;V8*>6]U<B!L;V=I;B!N86UE+B @5&AE<V4@
M8VAA<F%C=&5R<R!W:6QL(&%L=V%Y<R!B92!I;G1E<G!R971E9"!A<R!H879I
M;F<@=&AE:7(*<W!E8VEA;"!M96%N:6YG(&%S(&1E<V-R:6)E9"!A8F]V92X*
6+E-(($%55$A/4@I'<F5G($ML96EN"FYG
 
end
@eof

chmod 644 gettycb.1

echo x - logincb.1 '[non-ascii]'
$unpacker <<'@eof'
begin 644 logincb.1
M+F1E?48@(" @(" @(" @(" @(" @(" @(" @(" @(" @("!<(B!R961E9FEN
M92!F;V]T97(@;6%C<F\@9F]R($U%0PHN9',I2"!,;V-A; HN978Q"BY]10HN
M:69<7&XH*7,@)W-P('Q<7&XH+G!U+3%V+3%P"BYI9EQ<;B@I=" G<W @?%Q<
M;B@N<'4M,W8*+FEF;B G<W @?%Q<;B@N<'4M-'8*+G1L!UQ<*B@I2 <M("4@
M+0=<7"HH75<'"B=B< HN978*+BX*+FYR("E,(#8S=B @(" @(" @(" @(" @
M(" @(" @(" @("!<(B!S970@<&%G92!L96YG=&@@9F]R(&1E8R!L87-E<@HN
M5$@@3$]'24Y#0B Q("),;V-A;"(*+E5#(#0*+E-(($Y!344*;&]G:6YC8B!<
M+2!S:6=N(&]N(&9R;VT@<F5M;W1E('1E<FUI;F%L(&9O<B!C86QL(&)A8VL*
M+E-((%-93D]04TE3"B]U<W(O;&]C86PO8FEN+VQO9VEN8V(@6RUL72!S<&5E
M9"!;;F%M95T*+E-(($1%4T-225!424]."DQO9VEN8V(@:7,@:6YT96YD960@
M=&\@8F4@;&EK92!L;V=I;B@Q*2!E>&-E<'0@=&AA="!I;G-T96%D(&]F(&5X
M96,G:6YG"BAE>&5C*#(I*2!A(&-O;6UA;F0@:6YT97)P<F5T97(@87,@<W!E
M8VEF:65D(&EN('1H92!U<V5R<R!E;G1R>2!I;B *+V5T8R]P87-S=V0@*'5S
M=6%L;'D@82!S:&5L;"!S=6-H(&%S('-H*#$I*2P@;&]G:6YC8B!S<&%W;G,@
M8W0H,2D@=&\*8V%L;"!B86-K('1H92!U<V5R(&%T(&$@<&AO;F4@;G5M8F5R
M(&%S<V]C:6%T960@=VET:"!T:&%T('5S97(N"DQO9VEN8V(@:7,@;F]R;6%L
M;'D@97AE8R=E9"!F<F]M(&=E='1Y8V(H,2DN("!'971T>6-B"F%N9"!L;V=I
M;F-B('1H=7,@<')O=FED92!A('-E8W5R92!R96UO=&4@;&]G:6X@=&\@=&AE
M('-Y<W1E;2X*+E *5&AE("UL(&]P=&EO;B!C875S97,@82!C86QL(&)A8VL@
M=&\@8F4@;&]G9V5D('1O('1H92!F:6QE("]U<W(O861M+V-B;&]G+@I4:&4@
M=7-E<B=S(&YA;64L(&-A;&P@8F%C:R!P:&]N92!N=6UB97(L(&%N9"!T:6UE
M(&]F(&-A;&P@8F%C:R!I<R!L;V=G960N"E1H92!S<&5E9"!P87)A;65T97(@
M:7,@=&AE(&QI;F4@<W!E960@9F]R('1H92!C86QL(&)A8VLN"BY0"DQO9VEN
M8V(@87-K<R!F;W(@>6]U<B!U<V5R(&YA;64@*&EF(&YO="!S=7!P;&EE9"!A
M<R!A;B!A<F=U;65N="D@86YD"GEO=7(@<&%S<W=O<F0N("!&;W(@861D960@
M<V5C=7)I='DL(&$@=7-E<B!W:71H;W5T(&$@<&%S<W=O<F0@=VEL;"!N;W0@
M8F4*8V%L;&5D(&)A8VLN("!);B!T:&ES(&-A<V4L(&%N(&5R<F]R(&UE<W-A
M9V4@=VEL;"!B92!P<FEN=&5D(&%F=&5R('EO=7(*=7-E<B!N86UE(&ES(&5N
M=&5R960@86YD('EO=2!W:6QL(&)E(')E+7!R;VUP=&5D(&9O<B!Y;W4@=7-E
M<B!N86UE+@I%8VAO:6YG(&ES('1U<FYE9"!O9F8@*'=H97)E('!O<W-I8FQE
M*2!D=7)I;F<@=&AE('1Y<&EN9R!O9B!Y;W5R"G!A<W-W;W)D+"!S;R!I="!W
M:6QL(&YO="!A<'!E87(@;VX@=&AE('=R:71T96X@<F5C;W)D(&]F('1H92!S
M97-S:6]N+@I!;B!I;G9A;&ED(&QO9VEN(&YA;64@=VEL;"!C875S92!A(')E
M<75E<W0@9F]R(&$@<&%S<W=O<F0N("!4:&ES(&ES(&1O;F4*=&\@;6%K92!I
M="!M;W)E(&1I9F9I8W5L="!F;W(@86X@=6YA=71H;W)I>F5D('5S97(@=&\@
M;&]G(&EN(&]N('1H92!S>7-T96T*8GD@=')I86P@86YD(&5R<F]R+B @069T
M97(@=&AR964@=6YS=6-C97-S9G5L;"!L;V=I;B!A='1E;7!T<RP@82!H86YG
M=7 *<VEG;F%L(&ES(&ES<W5E9"X*+E *268@>6]U(&1O(&YO="!C;VUP;&5T
M92!T:&4@;&]G:6X@<W5C8V5S<V9U;&QY('=I=&AI;B!O;F4@;6EN=71E+"!Y
M;W4@=VEL;"!B90IS:6QE;G1L>2!D:7-C;VYN96-T960N"BY0"D]N8V4@82!V
M86QI9"!L;V=I;B!A;F0@<&%S<W=O<F0@:&%V92!B965N(&5N=&5R960@82!M
M97-S86=E(&ES(&1I<W!L87EE9 IS87EI;F<@=&AA="!T:&4@;&EN92!W:6QL
M(&)E(&1I<V-O;FYE8W1E9"!A;F0@=&AA="!Y;W4@=VEL;"!B92!C86QL960@
M8F%C:RX*66]U<B!C86QL8F%C:R!P:&]N92!N=6UB97(@:7,@:6YC;'5D960@
M:6X@=&AE(&UE<W-A9V4N"DQO9VEN8V(@=&AE;B!S<&%W;G,@8W0H,2D*=VAI
M8V@@:&%N9W,@=7 @=&AE(&QI;F4@86YD(&-A;&QS('EO=2!B86-K(&EF(&$@
M8V%L;&]U="!L:6YE(&ES(&%V86EL86)L90HH;F]R;6%L;'DL('1H92!C86QL
M:6X@;&EN92!I<R!M861E(&$@8V%L;&]U="!L:6YE"BAS964@+W5S<B]L:6(O
M=75C<"],+41E=FEC97,I('-O('1H870@=&AE<F4@=VEL;"!A;'=A>7,@8F4@
M82!C86QL;W5T(&QI;F4*879A:6QA8FQE*2X@($-T*#$I(&AA;F=S('5P('1H
M92!L:6YE(&%N9"!S<&%W;G,@82!G971T>2@Q*0IO;B!T:&%T(&QI;F4@<V\@
M=&AA="!Y;W4@;6%Y(&QO9R!I;B!I;B!T:&4@;F]R;6%L(&UA;FYE<B!W:&5N
M('1H92!C86QL"F)A8VL@:7,@86YS=V5R960@8GD@=&AE('EO=7(@;6]D96TN
M"BY32"!&24Q%4PHN8G(*+W5S<B]L;V-A;"]E=&,O9V5T='EC8@HN8G(*+W5S
M<B]L:6(O=75C<"],+41E=FEC97,*+E-((%-%12!!3%-/"F-T*#$I+"!L;V=I
M;B@Q*2P@9V5T='EC8B@Q*2X*+E-(($1)04=.3U-424-3"E1H92!F;VQL;W=I
M;F<@9&EA9VYO<W1I8W,@=VEL;"!A<'!E87(@:68@<')O8FQE;7,@;V-C=7(Z
M"BY44" Q-0HN0E(@(DQO9VEN(&EN8V]R<F5C="(@.@II9B!T:&4@=7-E<B!N
M86UE(&]R('1H92!P87-S=V]R9"!C86YN;W0@8F4@;6%T8VAE9"X*+E10"BY"
M4B B4V]R<GDL(&QO9VEN(&AA<R!N;R!P87-S=V]R9" M+2!N;W0@86QL;W=E
M9"!H97)E(2(*:68@=&AE('5S97(@;F%M92!H87,@;F\@87-S;V-I871E9"!P
M87-S=V]R9"X*+E10"BY"4B B8V%N;F]T(&-A;&P@8F%C:R M+2!C86YN;W0@
M;W!E;B N8V)T96QN;R!F;W(@<F5A9&EN9R(*:68@=&AE('5S97(@9&]E<R!N
M;W0@:&%V92!A(')E861A8FQE("YC8G1E;&YO(&EN(&AI<R]H97(@:&]M92!D
M:7)E8W1O<GDN"BY44 HN0E(@(F-A;FYO="!C86QL(&)A8VL@+2T@+F-B=&5L
M;F\@:7,@96UP='DB"FEF('1H92!U<V5R)W,@+F-B=&5L;F\@9FEL92!I<R!E
M;7!T>2X*+E10"BY"4B B8V%N;F]T(&-A;&P@8F%C:R M+2!I;G9A;&ED('1E
M;'!H;VYE(&YU;6)E<B(*:68@=&AE('!H;VYE(&YU;6)E<B!I;B!T:&4@=7-E
M<B=S("YC8G1E;&YO(&-O;G1A:6YS(&EN=F%L:60@<&AO;F4@;G5M8F5R"F-H
L87)A8W1E<G,@*'-E92!C="@Q*2DN"BY32"!!551(3U(*1W)E9R!+;&5I;@IH
 
end
@eof

chmod 644 logincb.1

echo x - gettycb.c
cat >gettycb.c <<'@EOF'
/*
 * gettycb.c
 *
 * gettycb is like getty(1) (set terminal type, modes, speed, and line
 * discipline) but used with logincb to call back the terminal.  This
 * provides a secure remote access to the system.
 *
 * Normally, there should be only one instance of gettycb running on a
 * system.  That is, only one line is used to answer calls.  The
 * /etc/inittab file would then contain the single gettycb entry such as:
 * "g2:2:respawn:/etc/gettycb -t 30 tty04 1200."  Once gettycb
 * answers a call, it exec's logincb which spawns the program ct(1) to do
 * the callback.  Ct uses the first available callout device it finds in
 * the L-Devices file (or Devices file for HDB uucp).  If the call-in line
 * (example tty04) is also used as a call-out line (example cul04) then
 * that call-out line should be the last one listed in the L-Devices file
 * so that the one call-in line will remain available to answer calls until
 * it is also finally chosen to call back on.
 * 
 */

#include <stdio.h>
#include <time.h>
#include <termio.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>

struct baud {
	int bin;
	char ascii[5];
} baud[] = {
{B300,"300"},
{B1200,"1200"},
{B2400,"2400"},
};
int baud_count = sizeof(baud)/sizeof(struct baud);

char usage[] = "usage: gettycb [-l] [-d] [-t timeout] line [300|1200|2400]\n";

main(argc,argv,envp)
int		argc;
char	**argv;
char	**envp;
{
	void login_timeout();
	long nap();
	void setbuf();
	unsigned long alarm();
	void exit();
	extern char *optarg;
	extern int optind;
	int cfd, i, timeout, c, log, debug;
	struct termio tty;
	char ttyname[64];
	char logname[64], *p;
	FILE *ifp,*dfp;
	int baud_index;

#ifndef DEBUG	/* compile with -DDEBUG to use current terminal for i/o */
	/* Close stdin, stdout, stderr.  This is actually only necessary when
	 * this program is not started by init. */
	close(0); close(1); close(2);

	/* Write error messages to the console since this program is usually
	 * started by init. */
	cfd = open("/dev/console",O_WRONLY);	/* stdin */
	dup(cfd);			/* stdout */
	dup(cfd);			/* stder */
#endif

	timeout = -1;	/* default is no timeout (negative values are invalid)*/
	log = 0;	/* default is don't log callback */
	debug = 0;	/* default is no gettycb debug logging */
	while ( (c = getopt(argc,argv,"ldt:")) != EOF )
		switch(c) {
		case 'd':
			debug = 1;
			break;
		case 'l':
			log = 1;
			break;
		case 't':
			for ( i = 0; i < strlen(optarg); i++) {
				/* only non-negative timeouts allowed */
				if ( !isdigit(optarg[i]) ) {
					fprintf(stderr,"%s: invalid timeout \"%s\".\n",argv[0],optarg);
					uexit(1);
				}
			}
			timeout = atoi(optarg);
			break;
		case '?':
			uexit(1);
			break;
		}

	if ( optind == argc ) {
		fprintf(stderr,"%s: no terminal line specified.\n",argv[0]);
		uexit(1);
	}
	strcpy(ttyname,"/dev/");
	strcat(ttyname,argv[optind]);

	/* get speed argument if any */
	baud_index = 0;	/* default to 300 baud */
	if ( ++optind < argc ) {
		for ( ; baud_index < baud_count; baud_index++ ) {
			if ( strcmp(argv[optind],baud[baud_index].ascii) == 0 )
				break;
		}
		if ( baud_index > baud_count ) {
			fprintf(stderr,"%s: invalid speed \"%s\".\n",argv[0],argv[optind]);
			uexit(1);
		}
	}

#ifndef DEBUG	/* compile with -DDEBUG to use current terminal for i/o */
	/* Close console so that tty will become stdin on open */
	close(0); close(1); close(2);
	/* Make the tty to open the controlling terminal */
	if ( setpgrp() < 0 ) {
		cfd = open("/dev/console",O_WRONLY);dup(cfd);dup(cfd);
		fprintf(stderr,"%s: setpgrp failed.  errno: %d\n",argv[0],errno);
	}

	if( open(ttyname,O_RDWR) != 0) { 	/* open stdin */
		cfd = open("/dev/console",O_WRONLY);dup(cfd);dup(cfd);
		fprintf(stderr,"%s: cannot open \"%s\".  errno: %d\n",argv[0],ttyname,errno);
		uexit(1);
	}
	if ( dup(0) < 0 || dup(0) < 0 ) {	/* create stdout, stderr */
		close(0);
		cfd = open("/dev/console",O_WRONLY);dup(cfd);dup(cfd);
		fprintf(stderr,"%s: cannot create stdout and stderr.\n",argv[0]);
		exit(1);
	}
#endif
	if ( debug ) {
		if ( (dfp = fopen("/tmp/gettycb.dbg","a")) == NULL )
			debug = 0;
		else
			fprintf(dfp,"line \"%s\" opened, initial speed is %s\n",ttyname,baud[baud_index].ascii );
	}


	/* Initially, set terminal to raw mode (read awakens on every
	 * character).  A BREAK will not generate an interrupt and will
	 * will be received as a NULL character (all zero bits).
	 * Output parity (even) is generated but input parity is not checked
	 * (INPCK is not set). */
	tty.c_iflag = ICRNL;
	tty.c_oflag = OPOST | ONLCR;
	tty.c_cflag = PARENB | CS7 | HUPCL | CREAD;
	tty.c_lflag = 0;
	tty.c_line = 0;
	tty.c_cc[VINTR]  = CDEL;
	tty.c_cc[VQUIT]  = CQUIT;
	tty.c_cc[VERASE] = CERASE;
	tty.c_cc[VKILL]  = CKILL;
	tty.c_cc[VMIN]   = 1;
	tty.c_cc[VTIME]  = 0;
	setline(0,&tty,baud[baud_index].bin);

	/* Print contents of /etc/issue to user's terminal */
	if ( (ifp = fopen("/etc/issue","r")) != NULL ) {
		char cn;
		while( (c=getc(ifp)) != EOF ) {
			cn = c;
			if ( write(1,&cn,1) != 1 ) exit(1);
		}
		fclose(ifp);
	}

	/* If 'timeout' was specified, hangup if nothing is entered at the
	 * login prompt within 'timeout' seconds. */
	if ( timeout != -1 ) {
		if ( signal(SIGALRM,login_timeout) < 0 ) {
			cfd = open("/dev/console",O_WRONLY);dup(cfd);dup(cfd);
			fprintf(stderr,"%s: signal() failed.  errno: %d\n",argv[0],errno);
			exit(1);
		}
		alarm((unsigned long)timeout);
	}

	setbuf(stdout,NULL);	/* no buffering */
	/* Prompt for login and read response one character at a time.  A
	 * BREAK (received as a NULL) is entered by the user to cause
	 * sequencing to the next line speed. */
	while (1) {
		printf("login: ");	/* prompt */
		if ( debug ) fprintf(dfp,"login prompt sent, rcvd chars:\n");
		p = logname;
		if ( read(0,p,1) != 1 ) exit(1);
		/* Turn off timer since something was entered (no effect
		 * if timer is not running). */
		alarm(0);
		while ( *p != NULL && *p != '\n' ) {
			if ( debug ) putc(*p,dfp);
			if ( write(1,p,1) != 1 ) exit(1);
			if ( read(0,++p,1) != 1 ) exit(1);
		}
		if ( *p == '\n' ) {
			/* re-prompt user if just carriage return was entered */
			if ( p > logname ) {
				/* logname entered, exit loop */
				putchar('\n');
				break;
			}
		} else {
			/* A break was sent, wait time for break to complete
			 * before setting to new speed.  Otherwise the same
			 * break may be misinterpreted as a new break at
			 * the new speed. */
			nap(500L);
			/* want baud_index to reflect to last tried speed */
			baud_index = (baud_index + 1) % baud_count;
			setline(0,&tty,baud[baud_index].bin);
			if ( debug ) fprintf(dfp,"\nbreak received, sequenced to %s\n",baud[baud_index].ascii);
		}
		putchar('\n');
	}

	*p = 0;	/* terminate the logname string (which could be empty) */
	if ( debug ) {
		fprintf(dfp,"\nlogin of \"%s\" received, exec logincb at %s\n",logname,baud[baud_index].ascii);
		fclose(dfp);
	}

	/* Set terminal to cooked mode.  Output parity (even) is generated but
	 * input parity is not checked (INPCK is not set).  Receiving VINTR
	 * VQUIT characters will generate signals, as will receiving a BREAK.
	 * Turn on XON/XOFF flow control. */
	tty.c_iflag = BRKINT | IGNPAR | ISTRIP | ICRNL | IXON | IXANY;
	tty.c_oflag = OPOST | ONLCR | TAB3;
	tty.c_cflag = PARENB | CS7 | HUPCL | CREAD;
	tty.c_lflag = ISIG | ICANON | ECHO | ECHOK;
	tty.c_line = 0;
	tty.c_cc[VINTR]  = CDEL;
	tty.c_cc[VQUIT]  = CQUIT;
	tty.c_cc[VERASE] = CERASE;
	tty.c_cc[VKILL]  = CKILL;
	tty.c_cc[VEOF]   = CEOF;
	tty.c_cc[VEOL]   = CNUL;
	setline(0,&tty,baud[baud_index].bin);

	if ( log )
		execl("/usr/local/bin/logincb","/usr/local/bin/logincb","-l",baud[baud_index].ascii,logname,(char *)0);
	else
		execl("/usr/local/bin/logincb","/usr/local/bin/logincb",baud[baud_index].ascii,logname,(char *)0);

	/* only get here if execl failed */
	close(0);close(1);close(2);
	cfd = open("/dev/console",O_WRONLY);dup(cfd);dup(cfd);
	fprintf(stderr,"%s: cannot exec logincb\n",argv[0]);
	exit(1);
}

/*
 * Exit and print usage message.
 */
uexit(earg)
int earg;
{
	fprintf(stderr,"%s",usage);
	exit(earg);
}

/*
 * Time expired for login entry.
 */
void
login_timeout()
{
	exit(1);
}

/*
 * Set the line 'fd' to the characteristics specified by 'ttyp' augmented
 * by the speed in 'cbaud'.
 */
setline(fd,ttyp,cbaud)
int fd;
struct termio *ttyp;
int cbaud;
{
	ttyp->c_cflag &= ~CBAUD;
	ttyp->c_cflag |= cbaud;
	if ( ioctl(fd,TCSETA,(char *)ttyp) == -1 ) exit(1);
	if ( ioctl(fd,TCFLSH,2) == -1 ) exit(1);
}

/*
 * Delay program.  Used instead of speep() when more granularity is needed.
 */
long
nap(msec)
long	msec;
{
	struct timeval tp;
	struct timezone tzp;
	unsigned long	start_sec;
	long	start_usec;
	long	target_usec;
	long	now_usec;

	gettimeofday(&tp,&tzp);
	start_sec = tp.tv_sec;
	start_usec = tp.tv_usec;
	target_usec = start_usec + (msec * 1000L);
	now_usec = start_usec;
	while(now_usec < target_usec)
	{
		gettimeofday(&tp,&tzp);
		now_usec = ((tp.tv_sec - start_sec) * 1000000L) + tp.tv_usec;
	}
	return((now_usec - start_usec) / 1000L);
}
@EOF

chmod 644 gettycb.c

echo x - logincb.c
cat >logincb.c <<'@EOF'
/*
 * logincb.c
 *
 * logincb is like login(1) but instead of exec'ing the program specified
 * in the last field of the users line in /etc/passwd (normally a shell),
 * the user is called back at a phone number found in the file .cbtelno
 * in his/her home directory.  This program is exec'ed by gettycb.  Together
 * they provide a secure remote access to the system.
 *
 */

#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <pwd.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
#include <ctype.h>
#include <time.h>

#define MAXSPNM	5
#define MAXLGNM	64
#define MAXTN	256	/* max length telephone number */

char usage[] = "usage: logincb [ -l ] speed [ name ]\n";

main(argc,argv,envp)
int	argc;
char	**argv;
char	**envp;
{
	extern int optind;
	void login_timeout();
	char *getlog();
	struct passwd *pw, *getpwnam();
	char *pass, *crypt_pass, *getpass(), *crypt();
	char logname[MAXLGNM+1], speed[MAXSPNM+1];
	int i, c, log;

	log = 0;	/* logging off by default */
	while ( (c = getopt(argc,argv,"l")) != EOF )
		switch(c) {
		case 'l':
			log = 1;
			break;
		case '?':
			uexit(1);
			break;
		}

	if ( optind == argc ) {
		fprintf(stderr,"%s: no terminal speed specified.\n",argv[0]);
		uexit(1);
	}
	/* Process arguments */
	if ( argc == optind || argc > optind+2)
		uexit(1);
	/* copy speed argument */
	if ( strlen(argv[optind]) > MAXSPNM ) {
		fprintf(stderr,"%s: invalid speed \"%s\".\n",argv[0],argv[optind]);
		uexit(1);
	}

	/* One minute to complete login, else hangup */
	if ( signal(SIGALRM,login_timeout) < 0 ) {
		fprintf(stderr,"%s: signal() failed.  errno: %d\n",argv[0],errno);
		exit(1);
	}
	alarm((unsigned long)60);

	strcpy(speed,argv[optind]);
	/* copy logname argument if supplied */
	if ( argc == ++optind + 1 ) {
		if ( strlen(argv[2]) > MAXLGNM ) {
		fprintf(stderr,"%s: name too long \"%s\".\n",argv[0],argv[optind]);
		uexit(1);
		}
		strcpy(logname,argv[optind]);
	} else
		getlog(logname);

	/* Prompt for valid login name and password and then call the
	 * phone number associated with that user.  Exit after three invalid
	 * login attempts. */
	for ( i=0; i < 3; i++ ) {
		if ( i != 0 ) {
			printf("Login incorrect\n");
			getlog(logname);
		}
		/* Get password entry associated with logname */
		pw = getpwnam(logname);
		/* pw = NULL implies logname invalid */
		if ( pw != NULL && strlen(pw->pw_passwd) == 0 ) {
			/* valid login name with no password */
			printf("Sorry, login has no password -- not allowed here!\n");
			continue;
		}
		/* Prompt for password (echo turned off).  This is done even
		 * though the login name may be invalid, makes it more
		 * difficult to guess a valid logname-password. */
		pass = getpass("Password: ");
		/* Callback if logname and password are valid */
		if(pw != NULL && strcmp(crypt(pass,pw->pw_passwd),pw->pw_passwd) == 0) {
			alarm(0);	/* stop timeout */
			/* does not return */
			callback(logname,pw->pw_dir,speed,log);
		}
	}
	exit(1);		/* 3 failed attempts */
}

char *
getlog(log)
char *log;
{
	char *gets();

	log[0] = 0;	/* initialize to empty string */
	do {
		printf("login: ");
		gets(log);
	} while ( log[0] == 0 );
	return( log );
}

/*
 * exit and print usage message.
 */
uexit(earg)
int earg;
{
	fprintf(stderr,"%s",usage);
	exit(earg);
}

/*
 * Time expired for login entry.
 */
void
login_timeout()
{
	exit(1);
}

static char nstdin[] = "/tmp/logincb.in";
static char nstdout[] = "/tmp/logincb.out";
static char nstder[] = "/tmp/logincb.er";
/*
 * Callback the terminal of user 'usrnm'  on a callback line with speed
 * 'speed'.  The user's home directory is 'usrdir' which must contain the file
 * .cbtelno which contains the users callback telephone number.  Log the 
 * callback if 'log' is nonzero.
 */
callback(usrnm,usrdir,speed,log)
char *usrnm;
char *usrdir;
char *speed;
int log;
{
	FILE *fp;
	char cbfname[MAXPATHLEN];
	char telno[MAXTN];
	int forkret;
	char *s;

	strcpy(cbfname,usrdir);
	strcat(cbfname,"/.cbtelno");
	if ( (fp=fopen(cbfname,"r")) == NULL ) {
		fprintf(stderr,"cannot call back -- cannot open %s for reading.\n",cbfname);
		exit(1);
	}
	if ( fscanf(fp,"%s",telno) == EOF ) {
		fprintf(stderr,"cannot call back -- %s is empty.\n",cbfname);
		exit(1);
	}
	/* Check for valid phone number (wanted to use strcspn() here but it
	 * didn't seem to work right). */
	for ( s = telno; *s != '\0'; s++ ) {
		if ( !isdigit(*s) && *s != '-' && *s != '=' && *s != '*' && *s != '#' ) {
			fprintf(stderr,"cannot call back -- %s contains an invalid telephone number \"%s\".\n",cbfname,telno);
			exit(1);
		}
	}

	/* Log the callback */
	if (log) {
		long ltime;
		struct timeval t;
		struct timezone tz;
		int fd;
		/* Create log file (with proper permissions) if it doesn't
		 * already exist. */
		if ( (fd=open("/usr/adm/cblog",O_WRONLY|O_CREAT,0644)) >= 0 ) {
			/* Get file pointer so can use fprintf */
			fp = fdopen(fd,"a");
			/* Can't just use ctime() here to format the date 
			 * because it uses TZ which isn't defined when this
			 * program runs from init. */
			gettimeofday(&t,&tz);
			ltime = t.tv_sec - (tz.tz_minuteswest * 60);
			fprintf(fp,"%s %s %s",usrnm,telno,asctime(gmtime(&ltime)));
			fclose(fp);
		}
	}

	printf("The line will now be disconnected and you will be called\n");
	printf("back at the telephone number \"%s\".  Your modem\n",telno);
	printf("must be able to answer the call.  This may take up to 3\n");
	printf("minutes, a longer delay means the callback was unsuccessful.\n");
	fflush(stdout);

	/* Spawn ct(1) to call back the terminal that has called in.  Ct will
	 * search the L-Devices file (or Devices, for HDB uucp) for an
	 * available callout line.  If found, it will callback on that line
	 * and then spawn a getty on the line for the user to log in on.
	 * We need to close the current line because it may be a valid
	 * call back line in the L-Devices file but ct will not be able
	 * to open it if this process already has it open.  (For example, if
	 * the current line is tty04 (call-in line) and cul04 (call-out line)
	 * is the line ct picks to call back on, it will not be able to
	 * open cul04 with tty04 still open.  This is because cul04 is of
	 * higher priority than tty04 and tty04 already has a successful
	 * open on it (refer to modem(7).)
	 *
	 * However, ct(1) seems to need stdin, stdout, and stderr to work
	 * properly (the callback hangs up immediately after the connection
	 * is made otherwise).  Re-create them here and associate tham with
	 * dummy files. */
	close(0);
	close(1);
	close(2);
	/* Don't want the call-in line to be the controlling terminal */
	setpgrp();
	/* Start from scratch to avoid potential open permission problems */
	unlink(nstdin);unlink(nstdout);unlink(nstder);
	if ( open(nstdin,O_RDWR|O_CREAT,0644) != 0 ||
	 open(nstdout,O_WRONLY|O_CREAT,0644) != 1 ||
	 open(nstder,O_RDWR|O_CREAT,0644) != 2 )
		exit(1);

	/* Ct asks if it's ok to hangup the line so put a 'y' in the
	 * stdin file.  */
	if ( write(0,"y\n",2) != 2 )
		exit(1);

	/* Instead of just exec'ing ct here, spawn it and have the parent
	 * exit.  Ct will be 'adopted' by init (pid=1).  This way, when
	 * logincb is exec'ed by gettycb and gettycb is marked for "respawn"
	 * in /etc/inittab, an new gettycb is started to answer new calls
	 * on the current line.  Otherwise, the current line would not be
	 * availabe to answer calls until the current callback session
	 * (potentially called back on a different line) is over.
	 *
	 * Note that it is important that the line specified in a gettycb
	 * inittab entry (ex. tty04) be made (with mknod(1)) as a 'call-in'
	 * device and the call-out devices in L-Devices (ex. cul04
	 * and cua04) be make as 'call-out' devices.  This is so that when
	 * a callout occurs on the same line as a (the) line with gettycb
	 * running on it (respawned), the open of the line (tty04) by gettycb 
	 * will lose out to the open of the line (cul04) by logincb when
	 * the call back is established.  That is, the open of cul04 by
	 * logincb will complete but the open of tty04 will become blocked.
	 * This is because a call-out device is a higher priority device than
	 * a call-in device.  Refer to modem(7).
	 */
	forkret = fork();
	if ( forkret == -1 ) {
		/* error msg goes to file */
		fprintf(stderr,"fork() failed, errno: %d\n",errno);
		exit(1);
	}
	if ( forkret != 0 )
		exit(0);	/* parent -- exit */
	/* spawn ct with debugging (-x9) so any call-back problems can
	 * be analyzed in nstderr */
	execl("/usr/bin/ct","/usr/bin/ct","-x9","-s",speed,telno,(char *)0);
	fprintf(stderr,"execl() of ct failed, errno: %d\n",errno);
	exit(1);
}
@EOF

chmod 644 logincb.c

rm -f /tmp/unpack$$
exit 0

chet@arc.UUCP (Chet Wood) (05/19/89)

In article <180004@mechp10.UUCP>,  Greg Klein writes:

> About a month ago I posted a request for getty and login source code that
> I could use to write a callback program.  Here's what I came up with.

Thanks for posting this, Greg. But it looks like the cornerstone of
your program is ct(1), which I can't find a hint of on my SunOS4.0.

Does anybody have a call back program that'll work under BSD? 

Thanks in advance,

Chet Wood                       ~                         (408)727-3357
     arc!chet@apple.COM         .  Advansoft Research Corporation
          chet@arc.UUCP         .       4301 Great America Parkway
               apple!arc!chet   .            Santa Clara, CA 95054, USA

mikey@shuksan.UUCP (Mike Fields) (05/20/89)

In article <324@arc.UUCP>, chet@arc.UUCP (Chet Wood) writes:
> In article <180004@mechp10.UUCP>,  Greg Klein writes:
> 
> > About a month ago I posted a request for getty and login source code that
> > I could use to write a callback program.  Here's what I came up with.
> 
> Does anybody have a call back program that'll work under BSD? 
> 
> Thanks in advance,
> 
> Chet Wood                       ~                         (408)727-3357
>      arc!chet@apple.COM         .  Advansoft Research Corporation
>           chet@arc.UUCP         .       4301 Great America Parkway
>                apple!arc!chet   .            Santa Clara, CA 95054, USA

I asked the same question some time ago and was sent the following 
program (it is fairly short and it works! - not fancy - add your own
bells and whistles)


>From: ssc-vax!uw-beaver!rutgers!hardy.nbi.com!harlan (Harlan Olson)
X-Mailer: ELM [version 2.2 PL6]

Maybe this might help you.

-- 
Harlan Olson
Customer Support Training        |       2995 Wilderness Pl.
303/443-9892 x2208               |       Boulder, CO  80301
{alegra,ucbvax,ncar,isieng}!nbires!hardy!harlan (USENET)



-----------------cut here ---------------------
#include <sgtty.h>

/*
 * Call back program
 * CHANGE THE PHONE NUMBER TO YOUR OWN!!!
 * To compile: cc -O -o callback callback.c
 * To use: after logging in as normal, type: exec callback
 * The exec is a shell internal command which causes the shell to execute the
 * specified command without forking.  This is necessary because callback must
 * be run as the top-level process of a login session.
 */

char *phone_number = "9,7763232";

main ()
  {
	struct sgttyb sgttyb;
	int oflags, olbits, lbits = LNOHANG|LNOMDM;

	sleep (3);
	ioctl (0, TIOCLGET, &olbits);
	ioctl (0, TIOCLBIS, &lbits);

	ioctl (0, TIOCGETP, &sgttyb);
	oflags = sgttyb.sg_flags;
	sgttyb.sg_flags &= ~ECHO;
	ioctl (0, TIOCSETP, &sgttyb);

	sleep (2);
	write (1, "+++", 3);
	sleep (2);

	write (1, "AT Z\r", 5);
	sleep (2);

	write (1, "AT H0\r", 6);
	sleep (3);

	write (1, "AT V0 DT ", 9);
	write (1, phone_number, strlen(phone_number));
	write (1, "\r", 1);
	sleep (23);
	ioctl (0, TIOCFLUSH, 0);

	ioctl (0, TIOCLSET, &olbits);

	sgttyb.sg_flags = oflags;
	ioctl (0, TIOCSETP, &sgttyb);

	execl ("/bin/login", "login", (char *)0);
	write (1, "Whoops!\r\n", 9);
	sleep (3);
}




-- 
Mikey (yes "he likes it!")
=======================================================   Mike Fields
uw-beaver!ssc-vax!shuksan!mikey  (206) 393-3768 [work]    12022 NE 138th Pl.
(alt) ssc-vax!mikey              (206) 821-3492 [home]    Kirkland, Wa. 98034

katzung@laidbak.UUCP (Brian Katzung) (05/22/89)

In article <324@arc.UUCP> chet@arc.UUCP (Chet Wood) writes:
>In article <180004@mechp10.UUCP>,  Greg Klein writes:
>
>> About a month ago I posted a request for getty and login source code that
>> I could use to write a callback program.  Here's what I came up with.
>
>Thanks for posting this, Greg. But it looks like the cornerstone of
>your program is ct(1), which I can't find a hint of on my SunOS4.0.
>
>Does anybody have a call back program that'll work under BSD? 

I was under the impression that ct (call terminal) was normally a link
to cu (call Un*x), but I don't remember for sure.  Check the cu or
tip man pages for hints.

On Sun machines, you don't have to do anything with getty or login.
The strategy I used is:  hangup, dial out on the dial out device
corresponding to the line on which you dialed in, and exit with
the HUPCL bit turned off.

Getty automatically resumes because you now have a connection with
a carrier and nothing happening on the dial out device.  These are
exactly the conditions which allow the dial in device to open!

This works because of the Sun feature of mutually exclusive dial in
and dial out minor devices for each line.  This scheme should work
for any other system with this feature.

The script I have is based on a cu- and tip-like program I wrote
called call.  It has options to leave HUPCL unset, and to exec
programs upon connection (in the callback case, anything that
exits quickly, such as /bin/true or /bin/exit, will do).

If you want the callback script (short) or the call program (medium),
send me some mail.  I suppose if there is enough interest, I could
post the sources.

A commissioned version of callback written in C is also available
as part of some sort of system adminstration package distributed
by UC Berkeley, I believe.  I can get you in contact with someone
for more info about this, if you like.

I may still have an old old version of kermit that I hacked to
run inside of call, too.

  -- Brian Katzung   ...!laidbak!katzung