[net.bugs.uucp] uucp thru Gandalf front-end

stewart (09/09/82)

This is in reponse to a news article from Alan Parker sent to
net.unix-wizar.  He wanted to run uucp with a site having a Gandalf
front end and needed the capability to send a single carriage return.

As an aside, he may also need the capability to send a real "break"
signal, not the hacked break (changing baud rate, etc.) found in most
versions of uucp.  (We needed it to communicate with NEIS in Golden,
CO.)  For this you should use the TIOCSBRK and TIOCCBRK options of
ioctl.  They came in 4.1; I installed them in our dz.c of 2.8.

Although the following code will allow uucico to send a single carriage
return and a lot of things previously impossible, there is still a problem:
uucico must still try to match a string coming from the called machine
before it can send that first carriage return!  Currently we just let it
time out.

The following should replace the procedure "sendthem()" in "conn.c".
You must also define PRIV_UIDS somewhere, either in conn.c or uucp.h.
			John Stewart 703-276-7900
............................................................
/***
 *      sendthem(str, fn)       send line of login sequence
 *      char *str;
 *
 *      return codes:  none
 *
 *	Modified: Bill Shannon - DEC
 *		  Sam Leffler - Sytek:  extended characters
 *		  J.C. Stewart - Plugged DEBUG security hole
 */

sendthem(str, fn)
char *str;
int fn;
{
	int nw, nulls, nlw = 1;
	char *strptr;

/*	DEBUG(5, "send %s\n", str);	/*!!! was */
	if (Debug >= 5) {
		if (getuid() <= PRIV_UIDS) {
			fprintf(stderr, "send %s\n", str);
		} else {
			fprintf(stderr, "send <something from L.sys>\n");
		}
	}
	if (prefix("BREAK", str)) {
		sscanf(&str[5], "%1d", &nulls);
			if (nulls <= 0 || nulls > 10)
				nulls = 3;
			/* send break */
			genbrk(fn, nulls);
			return;
	}

	if (strcmp(str, "EOT") == SAME) {
		write(fn, EOTMSG, strlen(EOTMSG));
			return;
	}

	for (strptr = str; *strptr; strptr++) {
		if (*strptr == '\\') switch(*++strptr) {
			case 's':
				DEBUG(5, "BLANK\n", "");
				*strptr = ' ';
				break;
			case 'd':
				DEBUG(5, "DELAY\n", "");
				sleep(1);
				continue;
			case 'r':
				DEBUG(5, "RETURN\n", "");
				*strptr = '\r';
				break;
			case 'b':
				if (isdigit(*(strptr+1))) {
					nulls = (*++strptr - '0');
					if (nulls <= 0 || nulls > 10)
						nulls = 3;
				} else
					nulls = 3;
					/* send break */
					DEBUG(5, "BREAK (%d nulls)\n", nulls);
					genbrk(fn, nulls);
					continue;
			case 'c':
				if (*(strptr+1) == '\0') {
					DEBUG(5, "NO NL\n", "");
					nlw = 0;
					continue;
				}
				DEBUG(5, "NO NL - MIDDLE IGNORED\n", "");
			default:
				DEBUG(5, "BACKSLASH\n", "");
				strptr--;
		}
		nw = write(fn, strptr, 1);
		ASSERT(nw == 1, "BAD WRITE %s", str);
	}
	if (nlw) {
		write(fn, "\n", 1);
	}
	return;
}