157416Smarkm
257416Smarkm   Three pieces of state need to be kept for each side of each option.
357416Smarkm   (You need the localside, sending WILL/WONT & receiving DO/DONT, and
457416Smarkm   the remoteside, sending DO/DONT and receiving WILL/WONT)
557416Smarkm
657416Smarkm	MY_STATE:	What state am I in?
757416Smarkm	WANT_STATE:	What state do I want?
857416Smarkm	WANT_RESP:	How many requests have I initiated?
957416Smarkm
1057416Smarkm   Default values:
1157416Smarkm	MY_STATE = WANT_STATE = DONT
1257416Smarkm	WANT_RESP = 0
1357416Smarkm
1457416Smarkm   The local setup will change based on the state of the Telnet
1557416Smarkm   variables.  When we are the originator, we can either make the
1657416Smarkm   local setup changes at option request time (in which case if
1757416Smarkm   the option is denied we need to change things back) or when
1857416Smarkm   the option is acknowledged.
1957416Smarkm
2057416Smarkm   To initiate a switch to NEW_STATE:
2157416Smarkm
2257416Smarkm	if ((WANT_RESP == 0 && NEW_STATE == MY_STATE) ||
2357416Smarkm			WANT_STATE == NEW_STATE) {
2457416Smarkm	    do nothing;
2557416Smarkm	} else {
2657416Smarkm	    /*
2757416Smarkm	     * This is where the logic goes to change the local setup
2857416Smarkm	     * if we are doing so at request initiation
2957416Smarkm	     */
3057416Smarkm	    WANT_STATE = NEW_STATE;
3157416Smarkm	    send NEW_STATE;
3257416Smarkm	    WANT_RESP += 1;
3357416Smarkm	}
3457416Smarkm
3557416Smarkm   When receiving NEW_STATE:
3657416Smarkm
3757416Smarkm	if (WANT_RESP) {
3857416Smarkm	    --WANT_RESP;
3957416Smarkm	    if (WANT_RESP && (NEW_STATE == MY_STATE))
4057416Smarkm		--WANT_RESP;
4157416Smarkm	}
4257416Smarkm	if (WANT_RESP == 0) {
4357416Smarkm	    if (NEW_STATE != WANT_STATE) {
4457416Smarkm		/*
4557416Smarkm		 * This is where the logic goes to decide if it is ok
4657416Smarkm		 * to switch to NEW_STATE, and if so, do any necessary
4757416Smarkm		 * local setup changes.
4857416Smarkm		 */
4957416Smarkm		if (ok_to_switch_to NEW_STATE)
5057416Smarkm		    WANT_STATE = NEW_STATE;
5157416Smarkm		else
5257416Smarkm		    WANT_RESP++;
5357416Smarkm*		if (MY_STATE != WANT_STATE)
5457416Smarkm		    reply with WANT_STATE;
5557416Smarkm	    } else {
5657416Smarkm		/*
5757416Smarkm		 * This is where the logic goes to change the local setup
5857416Smarkm		 * if we are doing so at request acknowledgment
5957416Smarkm		 */
6057416Smarkm	    }
6157416Smarkm	}
6257416Smarkm	MY_STATE = NEW_STATE;
6357416Smarkm
6457416Smarkm* This if() line is not needed, it should be ok to always do the
6557416Smarkm  "reply with WANT_STATE".  With the if() line, asking to turn on
6657416Smarkm  an option that the other side doesn't understand is:
6757416Smarkm		Send DO option
6857416Smarkm		Recv WONT option
6957416Smarkm  Without the if() line, it is:
7057416Smarkm		Send DO option
7157416Smarkm		Recv WONT option
7257416Smarkm		Send DONT option
7357416Smarkm  If the other side does not expect to receive the latter case,
7457416Smarkm  but generates the latter case, then there is a potential for
7557416Smarkm  option negotiation loops.  An implementation that does not expect
7657416Smarkm  to get the second case should not generate it, an implementation
7757416Smarkm  that does expect to get it may or may not generate it, and things
7857416Smarkm  will still work.  Being conservative in what we send, we have the
7957416Smarkm  if() statement in, but we expect the other side to generate the
8057416Smarkm  last response.
81