
/*
 * Csh - a shell by PJAC
 * misc.c - misc routines
 */

#include "csh.h"

/*
 * a null command - always works
 */
do_colon(argc, argv)
char	**argv;
{
	return(OK);
}

do_cd(argc, argv)
char	**argv;
{
	char	*p;

	if(argc == 1)
		p = HOME;
	else
		p = argv[1];
	if(chdir(p) < 0){
		inv_dir(p);
		return(ERR);
	}
#ifndef	MSDOS
	if(argc == 1)
		strcpy(CWD, p);
	else
#endif
	get_dir();
	return(OK);
}

do_pwd(argc, argv)
char	**argv;
{
	put_s(CWD);
	put_s("\n");
	return(OK);
}

#ifdef	MSDOS
do_drive(argc, argv)
char	**argv;
{
	char	tbuf[5];
	int	c;

	if(argc <= 1){
		tbuf[0] = CWD[0];
		strcpy(tbuf + 1, "'\n");
		put_s("Current drive is '");
		put_s(tbuf);
		return(OK);
	}
	c = *argv[1];
	if(c >= 'A' && c <= 'Z')
		c += 'a' - 'A';
	else if(c < 'a' || c > 'z')
		syn_err();
	c -= 'a';
	bdos(0xe, c, 0);
	get_dir();
	return(OK);
}
#endif

do_echo(argc, argv)
char	**argv;
{
	argv++;
	while(*argv){
		put_s(*argv++);
		if(*argv)
			put_s(" ");
		else
			put_s("\n");
	}
	return(OK);
}

do_exit(argc, argv)
char	**argv;
{
	int	res;

	if(Pflag)
		return(OK);
	if(argc < 2)
		_exit(0);	/* never returns */
	if(arg_eval(--argc, ++argv, &res) == OK){
		if(Lflag)
			return(ERR);
		_exit(res);	/* no return */
	}
	expr_err();
	return(ERR);
}

put_prompt(prompt)
char	*prompt;
{
	char	lbuf[128];
	char	*p, *q;

	if(in_cshrc || sh_script || Cur_ins != in_bufs)
		return;
	for(p = lbuf ; *prompt ; prompt++)
		if(*prompt == '\\'){
			if(!*(prompt+1)){
				*p++ = *prompt;
				continue;
			}
			*p++ = *++prompt;
			continue;
		}
		else if(*prompt == '!'){
			q = my_Itoa(Curcnum);
			while(*p = *q)
				p++, q++;
		}
		else if(*prompt == '^'){
			q = CWD;
			while(*p = *q)
				p++, q++;
		}
		else *p++ = *prompt;
	*p = 0;
	put_s(lbuf);
}

get_dir()
{
	getcwd(CWD, MAX_CWD);
	to_low(CWD);
	to_fslash(CWD);
}

static	put_out();

put_s(str)
char	*str;
{
	put_out(1, str);
}

puterr(str)
char	*str;
{
	put_out(in_efd, str);
}

static
put_out(fd, str)
char	*str;
{
#if	0
	char	*p, *q;
	static	char	crlf[] = "\r\n";

	for(p = str ; q = index(p, '\n') ; p = q + 1){
		write(fd, p, q - p - 1);
		write(fd, crlf, 2);
	}
	if(*p)
		write(fd, p, strlen(p));
#else
	write(fd, str, strlen(str));
#endif
}

char	*
strsave(str)
char	*str;
{
	char	*s;

	s = mmalloc(strlen(str)+1);
	strcpy(s, str);
	return(s);
}

/*
 * my own allocation routine, recalls the main loop if got no more mem
 */
char	*
mmalloc(size)
unsigned size;
{
	char	*s;
	if((s = malloc(size)) == 0)
		longjmp(env_main, NOMEM);
	return(s);
}

char	*
rindex(str, c)
register char	*str, c;
{
	char	*res = 0;

	while(*str)
		if(c == *str++)
			res = str - 1;
	return(res);
}

char	*
index(str, c)
register char	*str, c;
{
	while(*str)
		if(c == *str++)
			return(--str);
	return(0);
}

/*
 * convert to forward slashes
 */
to_fslash(str)
char	*str;
{
	while(*str)
		if(*str++ == '\\')
			*(str-1) = '/';
}

#ifdef	MSDOS
to_bslash(str)
char	*str;
{
	while(*str)
		if(*str++ == '/')
			*(str-1) = '\\';
}
#endif

to_low(str)
char	*str;
{
	while(*str){
		if(*str >= 'A' && *str <= 'Z')
			*str += 'a' - 'A';
		str++;
	}
}

char	*
my_Itoa(val)
{
	char	*itoa();
	static	char	mybuf[20];

	return(itoa(val, mybuf, 10));
}

/*
 * turn off top bits
 */
un_spec(str)
register char	*str;
{
	while(*str)
		*str++ &= 0177;
}

/*
 * skip onto next space char
 */

char	*
skipsp(p)
char	*p;
{
	char	*q;

	while(*p){
		for(q = IFS ; *q ; q++)
			if(*q == *p)
				break;
		if(!*q)
			break;
		p++;
	}
	if(*p == '\0')
		return(NULL);
	return(p);
}

#ifdef	MSDOS

#include <dos.h>
/*
 * horrible hack time to change controling terminal from a to b
 */
do_ctty(argc, argv)
char	**argv;
{
	int	ofd = -1;
	int	ifd;
	union	REGS	R;

	if(argc < 2){
		puterr("No device specified.\n");
		return(ERR);
	}
	ifd = open(argv[1], 0);
	if(ifd >= 0)
		ofd = open(argv[1], 1);
	if(ifd < 0 || ofd < 0){
		if(ifd >= 0)
			close(ifd);
		if(ofd >= 0)
			close(ofd);
		puterr("Can't open '");
		puterr(argv[1]);
		puterr("'.\n");
		return(ERR);
	}
	R.h.ah = 0x44;
	R.h.al = 0;
	R.x.bx = ifd;
	intdos(&R, &R);
	if(R.x.cflag || (R.x.dx & 0x80) == 0){
		close(ifd);
		close(ofd);
		puterr("Bad device.\n");
		return(ERR);
	}
	R.h.ah = 0x44;
	R.h.al = 01;
	R.x.bx = ifd;
	R.x.dx &= 0xDF;	/* put terminal into cooked mode */
	intdos(&R, &R);
	dup2(ifd, in_ifd);
	dup2(ofd, in_ofd);
	dup2(ofd, in_efd);
	close(ifd);
	close(ofd);
	return(OK);
}
#endif

#ifndef	MSDOS

char	*
itoa(val, buf, base)
char	*buf;
{
	char	tbuf[12];
	char	*p;
	static	char	cvt[] = "0123456789abcdef";

	p = tbuf + 11;
	*p-- = 0;
	do {
		*p-- = cvt[val % base];
	} while(val /= base);
	strcpy(buf, ++p);
	return(buf);
}

char	*
getcwd(buf, length)
char	*buf;
{
	char	*getwd();

	return(getwd(buf));
}

#endif
