/*
     ATP QWK MAIL READER FOR READING AND REPLYING TO QWK MAIL PACKETS.
     Copyright (C) 1992  Thomas McWilliams 
     Copyright (C) 1990  Rene Cougnenc
   
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 1, or (at your option)
     any later version.
     
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
     
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/	 

/*
system.c
*/

/*
 * DOS System-Dependant functions for Read.c
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "reader.h"
#include "system.h"
#include "ansi.h"
#ifdef USEDIRENT
#include <sys/types.h>
#include <dirent.h>
#endif

#ifdef DJD
#include <pc.h>
#include <dos.h>
#endif

#ifdef __TURBOC__
#include <dos.h>
#endif

#ifdef __MSDOS__
#include <dir.h>  /* this defines structure "ffblk" */
#endif

#ifdef WIN32
#include <direct.h>
#include <io.h>
#endif

/*
 * Deletes ALL files in a directory pointed by PathName. This is
 * system-dependant.
 */

void 
Erase(const char *PathName)
{
	char            Pattern[ MAXPATHS ] ; 

#if defined(USEDIRENT)
	
	DIR *dirp ;
	struct dirent *firp ;

	dirp = opendir(PathName);
	if(dirp!=NULL) {
		while((firp = readdir(dirp))!=NULL)
			if(firp->d_name[0] != '.' ) {
				sprintf(Pattern, "%s%c%s", PathName,SEP,firp->d_name);
				unlink( Pattern );
			}
		closedir(dirp);
	}else{
		printf("Can't seem to open %s\n", PathName );
	}

#elif defined(UNIXCMDS)
	sprintf(Pattern, "rm -f %s/*", PathName);
	system(Pattern);

#elif !defined(WIN32)  /* for dos, this method saves you from an annoying prompt */
                       /* see below for WIN32 variation */
	int             ok;
	char            tmp[130];
	char            cwd[130];
	struct	ffblk 	FileDoc ;

	GETWD (cwd, 128);
	sprintf( (char *) Pattern, "%s\\*.*", PathName);

	if ( (ok = findfirst( (char *) Pattern, &FileDoc, 0)) != 0 ) return ;
	while (!ok) {
		sprintf(tmp, "%s\\%s", PathName, FileDoc.ff_name);
		unlink(tmp);
		ok = findnext( &FileDoc );
	}
	CHPATH (cwd);
/* WIN32 below */	
#else

	int             ok;
	long            filegrouphandle;
	char            tmp[MAXPATHS];
    char            cwd[MAXPATHS];
	struct _finddata_t FileDoc ;

	GETWD (cwd, MAXPATHS - 2);
	sprintf( (char *) Pattern, "%s\\*.*", PathName);

	if ( (filegrouphandle = ok = _findfirst( (char *) Pattern, &FileDoc)) != 0 ) return ;
	while (!ok) {
		sprintf(tmp, "%s\\%s", PathName, FileDoc.name);
		unlink(tmp);
		ok = _findnext( filegrouphandle, &FileDoc );
	}
    _findclose (filegrouphandle);
	CHPATH (cwd);
#endif
}
/*-------------------------------------------------------------------------*/

#ifdef NEEDSTRI

int 
strnicmp(const char *s1, const char *s2, size_t n)
{
	while (n && *s1 && *s2) {
		if (tolower(*s1) != tolower(*s2))
			return (tolower(*s1) > tolower(*s2) ? 1 : -1);
		s1++;
		s2++;
		n--;
	}
	if (n) {
		if (*s1)
			return (1);
		if (*s2)
			return (-1);
	}
	return (0);
}

#ifndef ATPDBM

int 
stricmp(const char *s1, const char *s2)
{
	while (*s1 != '\0' && *s2 != '\0') {
		if (tolower(*s1) != tolower(*s2))
			return (tolower(*s1) > tolower(*s2) ? 1 : -1);
		s1++;
		s2++;
	}
	if (*s1)
		return (1);
	if (*s2)
		return (-1);
	return (0);
}

#endif

char           *
strlwr(char *s)
{
	char           *s1;

	s1 = s;
	while (*s1) {
		*s1 = tolower(*s1);
		s1++;
	}
	return (s);
}

char           *
strupr(char *s)
{
	char           *s1;

	s1 = s;
	while (*s1) {
		*s1 = toupper(*s1);
		s1++;
	}
	return (s);
}

#endif

#ifdef NEEDREADLINE

#ifndef UNIXCMDS 
#define STOPIT (int)'\r'
#else 
#define STOPIT (int)'\n'
#endif

char * readline( char *prmt, int scrollflag ) {

	static char rdlnbuf[128] ;
    extern char *luxptr ;
	char *buf, *tempr ;
	int cin = 0, idx = 0 , i, firsthere = TRUE ;

    buf = (char *) malloc( 128 ) ; /* inialize buffers */
    rdlnbuf[0] = buf[0] = 0 ;
    
	printf("%s",prmt);             /* display prompt */
 	if(luxptr != NULL){
        strcpy (rdlnbuf, luxptr);
		printf("%s\n", luxptr );
        up(1);
        right(14);
        buf[0] = 1 ;
	}
	fflush(stdout);
	while( ( cin = getch())!=STOPIT) {
		if( firsthere ) {
    		for(i=idx; i < 25 ; i++ ) printf(" "); /* clear line */
			for(i=idx; i < 25 ; i++ ) printf("\b"); buf[0] = 1 ;
            firsthere = FALSE ;
        }
    	if( cin > 31 ) {
			printf("%c", cin); buf[idx] = (char) cin ; idx++ ;
       		buf[idx] = 0 ;
			if ( idx  > 24 ) { idx-- ; printf("\b") ; } ;
    	} else if ( cin == '\b' && idx > 0 ) {  /* do backspace */
			printf("\b \b");
			buf[--idx] = 0 ;
		} else if ( cin == 0 ) { 
			buf[idx] = 0 ;
#ifdef __TURBOC__  /* check for special keys */
			tempr = NULL ; 
			if(luxptr == NULL) {
           switch ( cin = getch()){
				case 0x3b : tempr =  "help" ; break ;
				case 0x3c : tempr =  "tag help" ; break ;
				case 0x3d : tempr =  "tag list" ; break ;
				case 0x3e : tempr =  "qlist" ; break ;
				case 0x49 : tempr =  "-" ; break ;
				case 0x51 : tempr =  "+" ; break ;
                case 0x4f : tempr =  "last" ; break ;
				case 0x47 : tempr =  "1" ; break ;
                case 0x3f : tempr =  "show terms" ; break ;
				case 0x4c : tempr =  "N" ; break ;
				default: 
				break ;
			}
			if( tempr != NULL ) {
				strcpy ( buf, tempr);
				printf("\n");
				return buf ;
			}
			}
#endif
		} else {
            buf[idx] = 0 ; 
		}
        fflush(stdout);
	} 	
    printf("\n");
    if( buf[0] == 1 ) strcpy (buf, rdlnbuf);     
    return  buf ;

} ;

void /* dummy function for compatibility */ 
rl_initialize( void ) 
{
}

#endif

#ifdef NEEDTEMPNAM
char *mytempnam( const char *workpath, const char *rep ) {

    char *tp1, *tp2 ;
    static char    tbuf[MAXPATHS] ;
    char buffy[15] ;

    strcpy(buffy,"XXXXXX");
    tp2 = tbuf ;
    tp1 = mktemp( buffy ) ;
    if( tp1 != NULL ) {
    	strcpy( tbuf, workpath ); 
        while( *tp2 ) tp2++ ;
		tp2--  ;
		if( *tp2 != SEP ){
        	tp2++ ;
			*tp2 = SEP ;
            tp2++ ;
            *tp2 = '\0' ;
       }
       strcat(tbuf,rep) ;
   	   strcat(tbuf, tp1 ) ;
       tp1 = tbuf ;
   } 
   return  tp1 ;
} 

#endif 

#ifdef NEEDSYSTEM  
#ifdef UNIXCMDS
#define ATPSWC "-c"
#else 
#define ATPSWC "/C"
#endif

int
mysystem( char *command )
{
		pid_t  mpid, npid ;
		int    statloc ;
 		char  *shelbuf ;
	
		if ( (shelbuf = malloc ( MAXPATHS )) == NULL )
				return (0) ;
		shelbuf = getenv( SHELL) ;	

		mpid = fork() ;
		
		if ( mpid == 0 )		/* child */
		{
				execl( shelbuf, shelbuf, ATPSWC, command, NULL ) ;
				free ( shelbuf );
				abort();
		}
		else if ( mpid < 0 ) 
		{
				printf("Unable to fork %s\n", command );
				free ( shelbuf );
				return(0) ;
		}
		else					/* parent */
		{
		wmore:
				npid = wait( &statloc ) ;
				if ( npid != mpid ) goto wmore;
		}
		free ( shelbuf ) ;
		return(1);
}
						
#endif

#ifdef __MSDOS__

/* DosChPath() changes active path to new drive and directory */

int
DosChPath ( char *path ) {

	int driv ;

	 /* get drive letter from path */ 
	
	driv = toupper ( path[0] );

	 /*  test for valid drive designator at start of path */

	if ( (path[2] == SEP || path[2] == '/') && path[1] == ':' &&  driv > '@' && driv < 'Q' ){
		driv = ( driv & (char) 15 ) - 1 ; /* convert to numeric */
		if ( setdisk( driv ) < driv ) {
			printf("ERROR: can't set drive to '%c:'\n", driv )  ;
			sleep(4);
			return(-1);/* can't set drive */ 
		}
	}
	  /* change to new path */

	if( chdir( path ) != 0 ) {
			printf("ERROR: can't change path to '%s:'\n", path )  ;
			sleep(4);
			return(-1);/* can't change to path */ 
	}
	return(0);
}

#endif

#if defined(OS2) || defined(__MSDOS__)

/* addrive() prepends a drive designator to a path name */

void
addrive(char *path) {

	char tmp[MAXPATHS] ;
	int driv ;

	if ((path[2] != SEP && path[2] != '/' ) || path[1] != ':' ) {
#ifdef __EMX__
		driv = _getdrive();
#else
		driv = getdisk();
		driv = driv + 'A' ;
#endif
		if( path[0] != SEP && path[0] != '/' )
#ifdef DJD
			sprintf( tmp, "%c:%c%s", driv, '/', path );
#else
			sprintf( tmp, "%c:%c%s", driv, SEP, path );
#endif
		else
			sprintf( tmp, "%c:%s", (char) driv, path );
		strcpy( path ,tmp );
	}
}
#endif

#ifdef NEEDISKS

#ifdef __MSDOS__

/* get current active drive */

int 
getdisk( void ){

union REGS regs ;
int temp ;

regs.h.ah = 0x19 ;
regs.x.dx = 0 ;
regs.h.al = 0 ;

temp = intdos( &regs, &regs ) ;
return(temp & 15) ;

}

int 
setdisk( int driv ){

union REGS regs ;
int temp ;

regs.h.ah = 0x0e ;
regs.h.dl =  (char) ( driv & 127 ) ;
regs.h.al = 0 ;

temp = intdos( &regs, &regs ) ;
return(temp) ;
}

#endif
#endif

#ifdef DJD

char *
djgetwd( char *buf , int siz ) {

	char tmp[MAXPATHS] ;
	
	memset(tmp, 0 , siz - 1 );
	getwd(tmp);
        addrive( tmp );
	if( siz <= MAXPATHS )
		tmp[ siz - 1 ] = 0 ;
	strcpy( buf, tmp );
	return( buf );
}
#endif

#ifdef NEEDFIXPATH 
void
fixpath( char *path ) {

	char *tptr ;

	tptr = path ;
	while ( *tptr ) {
	if ( *tptr == '/' )
		*tptr = '\\' ;
	tptr++ ;
	}
}
#endif

