uplpos += bytes; upldp += bytes;  if (upldp >= upllen) upldp = -1; }
uplpos += bytes; upldp += bytes;  if (upldp >= upllen) upldp = -1; } }
int cmd_call(char *call[], int mode){    menuitem con[] =    {	{"~Reconnect", 'R', M_ITEM, (void *) 0x01},	{"~Exit", 'E', M_ITEM, (void *) 0x02},	{"\0", 0, M_END, 0}    };    menuitem fil[] =    {	{"~Open Logfile", 'O', M_ITEM, 0},	{"~Close Logfile", 'C', M_ITEM, 0},	{"Send ~Textfile", 'T', M_ITEM, 0},	{"Send ~Binary", 'B', M_ITEM, 0},	{"Send ~AutoBin", 'A', M_ITEM, 0},	{"\0", 0, M_END, 0}    };    menuitem mod[] =    {	{"~Slavemode", 'S', M_ITEM, 0},	{"~Talkmode", 'T', M_ITEM, 0},	{"~Rawmode", 'R', M_ITEM, 0},	{"\0", 0, M_END, 0}    };    menuitem win[] =    {	{"~Clear", 'C', M_ITEM, 0},	{"~Resize", 'R', M_ITEM, 0},	{"\0", 0, M_END, 0}    };    menuitem top[] =    {	{"~Connect", 'C', M_P_DWN, con},	{"~File", 'F', M_P_DWN, fil},	{"~Mode", 'M', M_P_DWN, mod},	{"~Window", 'W', M_P_DWN, win},	{"\0", 0, M_END, 0}    };    wint wintab;    fd_set sock_read;    fd_set sock_write;    char buf[MAX_BUFLEN];    char restbuf[MAX_PACKETLEN];    char parms[256];    int sevenplus = FALSE;    int sevenplcnt = 0;    int bytes;    int restbytes;    int parmsbytes;    int com_num;    int logfile = -1;    int uploadfile = -1;    int downloadfile = -1;    int binup = FALSE;    long uplsize = 0;    long uplpos = 0;    char uplbuf[128];		/* Upload buffer */    int upldp = 0;    int upllen = 0;    char *c, *t;    int extrach = 0;    t_gp gp;    t_win win_in;    t_win win_out;    WINDOW *swin = 0;    int cnt;    int crc = 0;    char s[80];    int flags = 0;    init_crc();    gp.dwn_cnt = 0;    wintab.next = 0;    if ((fd = connect_to(call)) == -1)	return FALSE;    interrupted = FALSE;    signal(SIGQUIT, cmd_intr);    signal(SIGINT, SIG_IGN);    signal(SIGTSTP, SIG_IGN);    fcntl(fd, F_SETFL, O_NONBLOCK);    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);    if (mode != RAWMODE)	start_screen(call);    switch (mode) {    case TALKMODE:	start_talk_mode(&wintab, &win_in, &win_out);	break;    case SLAVEMODE:	start_slave_mode(&wintab, &win_in, &win_out);	break;    case RAWMODE:	printf("Rawmode\n");    }    while (TRUE) {	FD_ZERO(&sock_read);	FD_SET(STDIN_FILENO, &sock_read);	FD_SET(fd, &sock_read);	FD_ZERO(&sock_write);	if (uploadfile != -1)	    FD_SET(fd, &sock_write);	if (select(fd + 1, &sock_read, &sock_write, NULL, NULL) == -1) {	    if (!interrupted && errno == EAGAIN)		continue;	    if (!interrupted)		perror("select");	    break;	}	if (FD_ISSET(fd, &sock_read)) {	    bytes = read(fd, buf, 511);	    if (bytes == -1 && errno != EWOULDBLOCK && errno != EAGAIN) {		if (errno != ENOTCONN)		    perror("read");		break;	    }	    if (gp.dwn_cnt != 0) {		ab_down(mode, swin, &wintab, buf, &bytes, &gp);		if (bytes == 0)		    continue;	    }	    do {		com_num = searche_key_words(buf, &bytes, parms, &parmsbytes, restbuf, &restbytes);		if (bytes != 0) {		    convert_cr_lf(buf, bytes);		    if (!sevenplus) {			writeincom(mode, &win_in, buf, bytes);		    } else {			for (cnt = 0; cnt < bytes; cnt++)			    if (eol(buf[cnt]))				sevenplcnt--;			dupdstatw(swin, s, FALSE);		    }		    if (downloadfile != -1)		    {			if (write(downloadfile, buf, bytes) != bytes)			{			    close(downloadfile);			    downloadfile = -1;			    statline(mode, "Error while writing file. Downloadfile closed.");			}		    }		    else		    if (logfile != -1) {			if (write(logfile, buf, bytes) != bytes) {			    close(logfile);			    logfile = -1;			    statline(mode, "Error while writing log. Log closed.");			}		    }		}		switch (com_num) {		case 0:		    {#if 0			/*			  FIXME! We should, no: WE MUST be able to turn off			  all remote commands to avoid mail bombs generating			  offensive mails with //e while sucking the BBS			*/			remotecommand(parms, parmsbytes);#endif		    }		    break;		case 1:		    {			start_ab_download(mode, &swin, &wintab, parms, parmsbytes, restbuf, restbytes, &gp, call);			restbytes = 0;			extrach = 0;		    }		    break;		case 2:		    {			if ((sevenplcnt = sevenplname(mode, &swin, &wintab, &downloadfile, &logfile, parms, parmsbytes, buf, bytes)) != -1)			    sevenplus = TRUE;		    }		    break;		case 3:		    {			if (!sevenplus)			    break;			write(downloadfile, key_words[3], strlen(key_words[3]));			convert_cr_lf(parms, parmsbytes);			write(downloadfile, parms, parmsbytes);			if (mode != RAWMODE) {			    delwin(swin);			    winclose(&wintab);			} else			    printf("\n");			statline(mode, "7+ Download finished.");			sevenplus = FALSE;			close(downloadfile);			downloadfile = -1;		    }		    break;		}		strncpy(buf, restbuf, restbytes);		bytes = restbytes;	    }	    while (restbytes != 0);	}	if (FD_ISSET(STDIN_FILENO, &sock_read)) {	    if ((mode & RAWMODE) == RAWMODE)		bytes = read(STDIN_FILENO, buf, 511);	    else {		bytes = readoutg(&win_out, &wintab, top, buf, 0x1d);		if (bytes == -1) {		    wclear(win_in.ptr);		    wrefresh(win_in.ptr);		    wclear(win_out.ptr);		    wrefresh(win_out.ptr);		    bytes = 0;		}	    }	    if (bytes > 0)		statline(mode, "");	    if (bytes > 1 && *buf == '~') {		buf[bytes] = 0;		switch (buf[1]) {		case '.':		    {			bytes = 0;			interrupted = TRUE;		    }		    break;		case '!':		    change_mode(mode, RAWMODE, &wintab, &win_in, &win_out, call);		    if (buf[2] != '\0' && buf[2] != '\n') {			c = buf + 2;			if ((t = strchr(c, '\n')) != NULL)			    *t = '\0';		    } else {			if ((c = getenv("SHELL")) == NULL)			    c = "/bin/sh";		    }		    fcntl(STDIN_FILENO, F_SETFL, 0);		    printf("\n[Spawning subshell]\n");		    system(c);		    printf("\n[Returned to connect]\n");		    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);		    change_mode(RAWMODE, mode, &wintab, &win_in, &win_out, call);		    continue;		case 'z':		case 'Z':		case 'Z' - 64:		    fcntl(STDIN_FILENO, F_SETFL, 0);		    kill(getpid(), SIGSTOP);		    statline(mode, "Resumed");		    fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);		    continue;		case '?':		case 'h':		case 'H':		    printf("\n\rTilde escapes:\n\r.  close\n\r!  shell\n\rZ  suspend\n\rs Stop upload\n\ro  Open log\n\rc  Close log\n\ru  Upload\n\ryd  YAPP Download\n\ryu  YAPP Upload\n\r");		    continue;		case 'S':		case 's':		    if (uploadfile != -1) {			statline(mode, "Upload file closed");			close(uploadfile);			uploadfile = -1;		    } else {			statline(mode, "No upload in progress");		    }		    continue;		case 'A':		case 'a':		case 'b':		case 'B':		case 'u':		case 'U':		    if (uploadfile != -1) {			statline(mode, "Already uploading");			continue;		    }		    if ((t = strchr(buf, '\n')) != NULL)			*t = '\0';		    t = buf + 2;		    while (*t != '\0' && isspace(*t))			t++;		    if (*t == '\0') {			statline(mode, "Upload requires a filename");			continue;		    }		    uploadfile = open(t, O_RDONLY);		    if (uploadfile == -1) {			statline(mode, "Unable to open upload file");			continue;		    }		    if (lseek(uploadfile, 0L, SEEK_END) != -1)			uplsize = lseek(uploadfile, 0L, SEEK_CUR);		    else			uplsize = 0;		    lseek(uploadfile, 0L, SEEK_SET);		    uplpos = 0;		    upldp = -1;		    upllen = 0;		    if (uplsize != -1) {			sprintf(s, "Uploading %ld bytes from %s", uplsize, t);			swin = opnstatw(mode, &wintab, s, 6, 50);			dupdstatw(swin, "bytes sent   : ", TRUE);		    } else {			sprintf(s, "Uploading from %s", t);			swin = opnstatw(mode, &wintab, s, 6, 50);			dupdstatw(swin, "bytes sent   : ", TRUE);		    }		    switch (buf[1]) {		    case 'a':		    case 'A':			{			    binup = TRUE;			    crc = 0;			    do {				upllen = read(uploadfile, uplbuf, 128);				if (upllen == -1) {				    close(uploadfile);				    uploadfile = -1;				    delwin(swin);				    winclose(&wintab);				    sprintf(s, "Error reading upload file: upload aborted");				    statline(mode, s);				    break;				}				crc = calc_crc(uplbuf, upllen, crc);			    }			    while (upllen > 0);			    lseek(uploadfile, 0L, SEEK_SET);			    sprintf(s, "#BIN#%ld#$%u#|000000#%s\r", uplsize, crc, t);			    write(fd, s, strlen(s));			    uplpos = 0;			    upldp = -1;			    upllen = 0;			}			break;		    case 'b':		    case 'B':			binup = TRUE;			break;		    case 'u':		    case 'U':			binup = FALSE;		    }		    continue;		case 'O':		case 'o':		    if ((t = strchr(buf, '\n')) != NULL)			*t = '\0';		    if (logfile != -1) {			close(logfile);			logfile = -1;		    }		    if (downloadfile != -1)		    {			close(downloadfile);			downloadfile = -1;		    }		    t = buf + 2;		    while (*t != '\0' && isspace(*t))			t++;		    if (*t == '\0')			t = "logfile.txt";		    if ((logfile = open(t, O_RDWR | O_APPEND | O_CREAT, 0666)) == -1) {			sprintf(s, "Unable to open %s", buf + 2);			statline(mode, s);		    } else			statbits(mode, 'L', 1);		    continue;		case 'C':		case 'c':		    if (logfile != -1) {			close(logfile);			logfile = -1;			statbits(mode, '-', 1);		    } else {			statline(mode, "Log file not open");		    }		    continue;		case 'Y':		case 'y':		    cmd_yapp(buf + 2, bytes - 2);		    continue;		case '~':		    bytes--;		    memmove(buf, buf + 1, strlen(buf));		    break;		case 'R':		case 'r':		    flags |= FLAG_RECONNECT;		    bytes = 0;		    interrupted = TRUE;		    continue;		case '0':		    mode = change_mode(mode, RAWMODE, &wintab, &win_in, &win_out, call);		    continue;		case '1':		    mode = change_mode(mode, SLAVEMODE, &wintab, &win_in, &win_out, call);		    continue;		case '2':		    mode = change_mode(mode, TALKMODE, &wintab, &win_in, &win_out, call);		    continue;		default:		    statline(mode, "Unknown '~' escape. Type ~h for a list");		    continue;		}	    }	    /* if (bytes == -1 && errno != EWOULDBLOCK && errno != EAGAIN) */	    /* if ((bytes == 0 && (mode & (TALKMODE|SLAVEMODE)) == 0) || (bytes == -1 && errno != EWOULDBLOCK && errno != EAGAIN)) */	    if (interrupted || (bytes == -1 && errno != EWOULDBLOCK && errno != EAGAIN)) {		if (!interrupted)		    perror("input");		break;	    }	    if (bytes > 0) {		sevenplus = FALSE;		if (uploadfile != -1) {		    statline(mode, "Ignored. Type ~s to stop upload");		    continue;		}		convert_lf_cr(buf, bytes);		if (write(fd, buf, bytes) == -1) {		    perror("write");		    break;		}	    }	    if (uploadfile != -1) {		if (uplsize == 0) {		    close(uploadfile);		    uploadfile = -1;		    delwin(swin);		    winclose(&wintab);		    statline(mode, "Upload complete: 0 bytes");		    continue;		}		if (upldp == -1) {		    upllen = read(uploadfile, uplbuf, 128);		    if (upllen == 0) {			close(uploadfile);			uploadfile = -1;			delwin(swin);			winclose(&wintab);			sprintf(s, "Upload complete: %ld bytes", uplpos);			statline(mode, s);			continue;		    }		    if (upllen == -1) {			close(uploadfile);			uploadfile = -1;			delwin(swin);			winclose(&wintab);			sprintf(s, "Error reading upload file: upload aborted at %ld bytes", uplpos);			statline(mode, s);			continue;		    }		    if (!binup)			convert_lf_cr(uplbuf, upllen);		    upldp = 0;		}		bytes = write(fd, uplbuf + upldp, upllen - upldp);		if ((bytes == 0 || bytes == -1) && errno != EWOULDBLOCK && errno != EAGAIN) {		    sprintf(s, "Write error during upload. Connection lost");		    statline(mode, s);		    perror("write");		    break;		}/*                      if (uplpos / 1024 != (uplpos + bytes) / 1024)   { */		/*      printf("\r%ld bytes sent    ", uplpos + bytes); */		sprintf(s, "%ld", uplpos + bytes);		dupdstatw(swin, s, FALSE);/*                      } */		uplpos += bytes;		upldp += bytes;		if (upldp >= upllen)		    upldp = -1;	    }	}    }    close(fd);    if (logfile != -1) {	close(logfile);	logfile = -1;    }    if (downloadfile != -1) {	    close(downloadfile);	    downloadfile = -1;    }    fcntl(STDIN_FILENO, F_SETFL, 0);    signal(SIGQUIT, SIG_IGN);    signal(SIGINT, SIG_DFL);    if (mode != RAWMODE)	endwin();    printf("*** Cleared\n");    if (flags & FLAG_RECONNECT) {	return TRUE;    } else {	return FALSE;    }}