unsigned i = 1;
unsigned i;
static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) {    crBegin;    random_init();    while (!do_ssh1_login(in, inlen, ispkt)) {	crReturnV;    }    if (ssh_state == SSH_STATE_CLOSED)        crReturnV;    if (cfg.agentfwd && agent_exists()) {        logevent("Requesting agent forwarding");        send_packet(SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);        do { crReturnV; } while (!ispkt);        if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {            bombout(("Protocol confusion"));            crReturnV;        } else if (pktin.type == SSH1_SMSG_FAILURE) {            logevent("Agent forwarding refused");        } else            logevent("Agent forwarding enabled");    }    if (!cfg.nopty) {	send_packet(SSH1_CMSG_REQUEST_PTY,	            PKT_STR, cfg.termtype,	            PKT_INT, rows, PKT_INT, cols,	            PKT_INT, 0, PKT_INT, 0,	            PKT_CHAR, 0,	            PKT_END);        ssh_state = SSH_STATE_INTERMED;        do { crReturnV; } while (!ispkt);        if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {            bombout(("Protocol confusion"));            crReturnV;        } else if (pktin.type == SSH1_SMSG_FAILURE) {            c_write("Server refused to allocate pty\r\n", 32);        }	logevent("Allocated pty");    }    if (cfg.compression) {        send_packet(SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);        do { crReturnV; } while (!ispkt);        if (pktin.type != SSH1_SMSG_SUCCESS && pktin.type != SSH1_SMSG_FAILURE) {            bombout(("Protocol confusion"));            crReturnV;        } else if (pktin.type == SSH1_SMSG_FAILURE) {            c_write("Server refused to compress\r\n", 32);        }	logevent("Started compression");	ssh1_compressing = TRUE;	zlib_compress_init();	zlib_decompress_init();    }    if (*cfg.remote_cmd)        send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END);    else        send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END);    logevent("Started session");    ssh_state = SSH_STATE_SESSION;    if (size_needed)	ssh_size();    ssh_send_ok = 1;    ssh_channels = newtree234(ssh_channelcmp);    begin_session();    while (1) {	crReturnV;	if (ispkt) {	    if (pktin.type == SSH1_SMSG_STDOUT_DATA ||                pktin.type == SSH1_SMSG_STDERR_DATA) {		long len = GET_32BIT(pktin.body);		from_backend(pktin.type == SSH1_SMSG_STDERR_DATA,			     pktin.body+4, len);	    } else if (pktin.type == SSH1_MSG_DISCONNECT) {                ssh_state = SSH_STATE_CLOSED;		logevent("Received disconnect request");                crReturnV;            } else if (pktin.type == SSH1_SMSG_AGENT_OPEN) {                /* Remote side is trying to open a channel to talk to our                 * agent. Give them back a local channel number. */                unsigned i = 1;                struct ssh_channel *c;                enum234 e;                for (c = first234(ssh_channels, &e); c; c = next234(&e)) {                    if (c->localid > i)                        break;         /* found a free number */                    i = c->localid + 1;                }                c = malloc(sizeof(struct ssh_channel));                c->remoteid = GET_32BIT(pktin.body);                c->localid = i;                c->closes = 0;                c->type = SSH1_SMSG_AGENT_OPEN;   /* identify channel type */                c->u.a.lensofar = 0;                add234(ssh_channels, c);                send_packet(SSH1_MSG_CHANNEL_OPEN_CONFIRMATION,                            PKT_INT, c->remoteid, PKT_INT, c->localid,                            PKT_END);            } else if (pktin.type == SSH1_MSG_CHANNEL_CLOSE ||                       pktin.type == SSH1_MSG_CHANNEL_CLOSE_CONFIRMATION) {                /* Remote side closes a channel. */                unsigned i = GET_32BIT(pktin.body);                struct ssh_channel *c;                c = find234(ssh_channels, &i, ssh_channelfind);                if (c) {                    int closetype;                    closetype = (pktin.type == SSH1_MSG_CHANNEL_CLOSE ? 1 : 2);                    send_packet(pktin.type, PKT_INT, c->remoteid, PKT_END);                    c->closes |= closetype;                    if (c->closes == 3) {                        del234(ssh_channels, c);                        free(c);                    }                }            } else if (pktin.type == SSH1_MSG_CHANNEL_DATA) {                /* Data sent down one of our channels. */                int i = GET_32BIT(pktin.body);                int len = GET_32BIT(pktin.body+4);                unsigned char *p = pktin.body+8;                struct ssh_channel *c;                c = find234(ssh_channels, &i, ssh_channelfind);                if (c) {                    switch(c->type) {                      case SSH1_SMSG_AGENT_OPEN:                        /* Data for an agent message. Buffer it. */                        while (len > 0) {                            if (c->u.a.lensofar < 4) {                                int l = min(4 - c->u.a.lensofar, len);                                memcpy(c->u.a.msglen + c->u.a.lensofar, p, l);                                p += l; len -= l; c->u.a.lensofar += l;                            }                            if (c->u.a.lensofar == 4) {                                c->u.a.totallen = 4 + GET_32BIT(c->u.a.msglen);                                c->u.a.message = malloc(c->u.a.totallen);                                memcpy(c->u.a.message, c->u.a.msglen, 4);                            }                            if (c->u.a.lensofar >= 4 && len > 0) {                                int l = min(c->u.a.totallen - c->u.a.lensofar, len);                                memcpy(c->u.a.message + c->u.a.lensofar, p, l);                                p += l; len -= l; c->u.a.lensofar += l;                            }                            if (c->u.a.lensofar == c->u.a.totallen) {                                void *reply, *sentreply;                                int replylen;                                agent_query(c->u.a.message, c->u.a.totallen,                                            &reply, &replylen);                                if (reply)                                    sentreply = reply;                                else {                                    /* Fake SSH_AGENT_FAILURE. */                                    sentreply = "\0\0\0\1\5";                                    replylen = 5;                                }                                send_packet(SSH1_MSG_CHANNEL_DATA,                                            PKT_INT, c->remoteid,                                            PKT_INT, replylen,                                            PKT_DATA, sentreply, replylen,                                            PKT_END);                                if (reply)                                    free(reply);                                free(c->u.a.message);                                c->u.a.lensofar = 0;                            }                        }                        break;                    }                }                	    } else if (pktin.type == SSH1_SMSG_SUCCESS) {		/* may be from EXEC_SHELL on some servers */	    } else if (pktin.type == SSH1_SMSG_FAILURE) {		/* may be from EXEC_SHELL on some servers		 * if no pty is available or in other odd cases. Ignore */	    } else if (pktin.type == SSH1_SMSG_EXIT_STATUS) {		send_packet(SSH1_CMSG_EXIT_CONFIRMATION, PKT_END);	    } else {		bombout(("Strange packet received: type %d", pktin.type));                crReturnV;	    }	} else {	    while (inlen > 0) {		int len = min(inlen, 512);		send_packet(SSH1_CMSG_STDIN_DATA,			    PKT_INT, len, PKT_DATA, in, len, PKT_END);		in += len;		inlen -= len;	    }	}    }    crFinishV;}