Exemple #1
0
/* Also: The contents of both buffers is monitored in order to
	check if they got overflowed during the MUX call. If so,
	the executation is aborted. */
int runExtension(char ** const command
	, const char * const line
	, char ** const newargs)
{	int clen, llen, xlen, nlen;
	struct REGPACK r, r2;
	char *muxCmd, *muxArg, *muxBuf, *p;

	assert(command);
	assert(*command);
	assert(line);
	assert(newargs);

	if((clen = strlen(*command)) >= BUFFER_SIZE_MUX_AE
	 || (llen = strlen(line)) >= BUFFER_SIZE_MUX_AE
	 || llen + clen >= BUFFER_SIZE_MUX_AE) {
		error_long_mux_line();
		return 0;
	}

	/* Duplicate & fill in the length bytes. */
		/* Both buffers must be located in the same segment */
	if((muxBuf = emalloc(2 * (BUFFER_SIZE_MUX_AE + 4))) == 0)
	 	return 0;

		/* fill everything with magic values */
	memset(muxBuf, (char)BUFFER_SIZE_MUX_AE, 2 * (BUFFER_SIZE_MUX_AE + 4));
	muxCmd = muxBuf + 2;
	muxArg = muxBuf + BUFFER_SIZE_MUX_AE + 4 + 2;
	memcpy(muxCmd, *command, clen);
	muxCmd[-1] = (char)clen;
	memcpy(muxArg, muxCmd, clen);
	memcpy(muxArg + clen, line, llen);
	muxArg[-1] = (char)(xlen = llen + clen);
/*	muxCmd[-2] = muxArg[-2] = (char)BUFFER_SIZE_MUX_AE;
		see above memset() */

	assert(xlen <= 255);

	/* 4dos v4 compatible space padding */
	memset(muxCmd + clen, ' ', BUFFER_SIZE_MUX_AE - clen);
	/* The command line is \xd terminated, for savety reasons an \0 is
		added too */
	strcpy(muxArg + xlen, "\xd");
	muxCmd[BUFFER_SIZE_MUX_AE]		/* Make sure the buffers is terminated */
	 = muxArg[BUFFER_SIZE_MUX_AE] = '\0';

/* Both strings have been prepared now; the MUX call is going to happen */
	r.r_ax = 0xae00;		/* Installable Commands check for extension */
	r.r_dx = 0xffff;		/* Magic value */
	r.r_cx = xlen | 0xff00;	/* length of command line tail (4dos v4) */
	r.r_ds = r.r_es = FP_SEG(muxBuf);
	r.r_bx = FP_OFF(muxArg);
	r.r_si = FP_OFF(muxCmd);
	r.r_di = 0;				/* Magic value 4dos v4 */
	memcpy(&r2, &r, sizeof(r2));
	intr(0x2f, &r);

	if((byte)muxCmd[-2] != BUFFER_SIZE_MUX_AE
#if BUFFER_SIZE_MUX_AE < 255
	 || (byte)muxCmd[-1] > BUFFER_SIZE_MUX_AE
#endif
	 || muxCmd[BUFFER_SIZE_MUX_AE]
	 || (byte)muxArg[-2] != BUFFER_SIZE_MUX_AE
#if BUFFER_SIZE_MUX_AE < 255
	 || (byte)muxArg[-1] > BUFFER_SIZE_MUX_AE
#endif
	 || muxArg[BUFFER_SIZE_MUX_AE]) {
		/* Yiek! That looks very much like an overflow!! */
		dprintf( ("[Memory corrupted during Installable Commands handler]\n") );
		longjmp(jmp_beginning, E_CorruptMemory);
	}


	switch(r.r_ax & 0xFF) {
	case 0x00:		/* No appropriate extension found */
		break;

	default:		/* Invalid response */
		dprintf( ("[Invalid response from Installable Commands handler: 0x%02x]\n", r.r_ax & 0xFF) );
		break;

	case 0xFF:		/* Is an extension -> execute the Installable Command */
		r2.r_ax = 0xae01;
		r2.r_cx = clen;
		intr(0x2f, &r2);

		if((byte)muxCmd[-2] != BUFFER_SIZE_MUX_AE
#if BUFFER_SIZE_MUX_AE < 255
		 || (byte)muxCmd[-1] > BUFFER_SIZE_MUX_AE
#endif
		 || muxCmd[BUFFER_SIZE_MUX_AE]
		 || (byte)muxArg[-2] != BUFFER_SIZE_MUX_AE
#if BUFFER_SIZE_MUX_AE < 255
		 || (byte)muxArg[-1] > BUFFER_SIZE_MUX_AE
#endif
		 || muxArg[BUFFER_SIZE_MUX_AE]) {
			/* Yiek! That looks very much like an overflow!! */
			dprintf( ("[Memory corrupted during Installable Commands handler]\n") );
			longjmp(jmp_beginning, E_CorruptMemory);
		}

		if(muxCmd[-1] == 0) {	/* The command had been processed */
			myfree(muxBuf);
			return 1;			/* Stop interpreting the command */
		}

		break;
	}

/* Cleanup: Adjust buffers and check for overflow */
	/* Check command and transform it back into C-style string */
	p = muxCmd + (byte)muxCmd[-1];
	while(--p >= muxCmd && isspace(*p));
	*++p = 0;
	if(*muxCmd) {
		if((p = erealloc(*command, (nlen = p - muxCmd) + 1)) == 0) {
			myfree(muxBuf);
			return 0;
		}
		StrFUpr(muxCmd);		/* make sure it's still uppercased */
		memcpy(*command = p, muxCmd, nlen + 1);
	} else {
		chkPtr(*command);
		StrFree(*command);
		nlen = 0;
	}

	/* Check the command line and transform it into a C-style string */
	/* Must terminate as line[BUFFER_SIZE] == 0 */
	p = muxArg + (byte)muxArg[-1];
	while(--p >= muxArg && *p == '\xd');
	*++p = 0;
	if((p - muxArg) >= nlen
	 && ((p - muxArg) - nlen != llen || strcmp(&muxArg[nlen], line) != 0)) {
	 	/* new arguments */
		/* Should never trigger, because the buffer for the command
			has the same size as the buffer for the argument itself.
			Because of the spurious length bytes:
				&muxArg[nlen] - muxBuf > BUFFER_SIZE_MUX_AE
			and because:
				strlen(&muxArg[nlen]) <= BUFFER_SIZE_MUX_AE
			both memory areas cannot overlap. */
		assert(&muxArg[nlen] - muxBuf > BUFFER_SIZE_MUX_AE);
		assert(strlen(&muxArg[nlen]) < BUFFER_SIZE_MUX_AE);
		strcpy(muxBuf, &muxArg[nlen]);
		*newargs = StrTrim(muxBuf);
		return 0;
	}

	myfree(muxBuf);
	return 0;			/* Proceed command processing as usual */
}
Exemple #2
0
void aliasexpand(char * const cmd, const int maxlen)
{	char *hbuf;				/* work buffer */
	char *cp, *p;
	unsigned ofs, *expanded, *he;
	int i, numExpanded;

	assert(cmd);
	assert(strlen(cmd) < maxlen);

	if((hbuf = malloc(maxlen)) == 0) {
		error_out_of_memory();
		return;
	}
	numExpanded = 0;
	expanded = 0;

redo:						/* iteration to expand all aliases */
	cp = ltrimcl(cmd);		/* skip leading whitespaces */

	/* Check if the user disabled alias expansion */
	if(*cp == '*') {
		memmove(cmd, cp + 1, strlen(cp));
		goto errRet;
	}

	/* Get the name of this command */
	for(p = hbuf; is_fnchar(*cp) || *cp == '.';)
		*p++ = *cp++;
	if(p == hbuf || is_pathdelim(*cp) || is_quote(*cp))
		/* no name || part of path -> no alias */
		goto errRet;

	*p = 0;
	StrFUpr(hbuf);			/* all aliases are uppercased */
	if((ofs = env_findVar(ctxtAlias, hbuf)) == (unsigned)-1)
		/* not found -> no alias */
		goto errRet;

	/* Prevent recursion by recording the offset of the found variable */
	for(i = 0; i < numExpanded; ++i)
		if(expanded[i] == ofs)		/* already used -> ignore */
			goto errRet;

	if((he = realloc(expanded, ++numExpanded)) == 0) {
		error_out_of_memory();
		goto errRet;
	}
	expanded = he;
	expanded[numExpanded - 1] = ofs;

	/************ Expand the command line "cp" with the alias at
						MK_FP(ctxtAlias, ofs)  ***********************/
	ofs += strlen(hbuf) + 1;		/* advance to value */
	if(_fstrlen(MK_FP(ctxtAlias, ofs)) < maxlen - strlen(cp)) {
		/* prepend alias value to remaining command line */
		_fstrcpy(TO_FP(hbuf), MK_FP(ctxtAlias, ofs));
		strcat(hbuf, cp);
		assert(strlen(hbuf) < maxlen);
		strcpy(cmd, hbuf);
		goto redo;				/* next expansion */
	}

	error_command_too_long();

errRet:							/* return to caller */
	free(expanded);
	free(hbuf);
}
Exemple #3
0
char *aliasexpand(const char * const Xcmd)
{	char *cmd;				/* work buffer */
	char *cp, *name, *alias;
	unsigned ofs, *expanded, *he;
	int i, numExpanded, newlen, len;

	assert(Xcmd);

	if((cmd = estrdup(Xcmd)) == 0)
		return (char*)Xcmd;

	numExpanded = 0;
	expanded = 0;
	name = 0;

redo:						/* iteration to expand all aliases */
	cp = ltrimcl(cmd);		/* skip leading whitespaces */

	/* Check if the user disabled alias expansion */
	if(*cp == '*') {
		*cp = ' ';
		goto errRet;
	}

	myfree(name);
	/* Get the name of this command */
	if((name = getCmdName(&(const char*)cp)) == 0 || is_pathdelim(*cp))
		goto errRet;

	StrFUpr(name);			/* all aliases are uppercased */
	if((ofs = env_findVar(ctxtAlias, name)) == (unsigned)-1)
		/* not found -> no alias */
		goto errRet;

	/* Prevent recursion by recording the offset of the found variable */
	for(i = 0; i < numExpanded; ++i)
		if(expanded[i] == ofs)		/* already used -> ignore */
			goto errRet;

	if((he = realloc(expanded, ++numExpanded)) == 0) {
		error_out_of_memory();
		goto errRet;
	}
	expanded = he;
	expanded[numExpanded - 1] = ofs;

	/************ Expand the command line "cp" with the alias at
						MK_FP(ctxtAlias, ofs)  ***********************/
	alias = ctxtP(ctxtAlias, ofs + strlen(name) + 1);
		/* Check that the total command line won't overflow MAX_INT */
	if((newlen = strlen(alias)) >= 0
	 && (len = strlen(cp)) >= 0 && ++len > 0 && newlen + len > 0) {
	 	int dst = cp - cmd;		/* destination index within cmd[] */
	 	if(newlen > dst) {
	 		/* need to increase the buffer */
	 		char *p;

	 		if((p = realloc(cmd, newlen + len)) == 0)
	 			goto errRet1;

	 		cmd = p;
	 	}
	 	/* else ignore to shrink the buffer; it will be done
	 		automatically with the next ALIAS expansion or when
	 		this function returns */
	 	assert(len);
	 	if(newlen != dst)
	 		/* need to move the command tail */
	 		memmove(&cmd[newlen], &cmd[dst], len);

		/* prepend alias value to remaining command line */
		memcpy(cmd, alias, newlen);
		goto redo;				/* next expansion */
	}

errRet1:
	error_long_internal_line();

errRet:							/* return to caller */
	myfree(expanded);
	myfree(name);

	return StrTrim(cmd);
}