dosbox-wii/src/shell/shell_cmds.cpp

704 lines
19 KiB
C++
Raw Normal View History

2009-05-02 23:03:37 +02:00
/*
2009-05-02 23:53:27 +02:00
* Copyright (C) 2002-2004 The DOSBox Team
2009-05-02 23:03:37 +02:00
*
* 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 2 of the License, 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
2009-05-03 00:02:15 +02:00
* GNU General Public License for more details.
2009-05-02 23:03:37 +02:00
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
2009-05-02 23:43:00 +02:00
2009-05-03 00:02:15 +02:00
/* $Id: shell_cmds.cpp,v 1.47 2004/09/18 10:20:54 qbix79 Exp $ */
2009-05-02 23:43:00 +02:00
2009-05-02 23:03:37 +02:00
#include <string.h>
2009-05-03 00:02:15 +02:00
#include <ctype.h>
2009-05-02 23:03:37 +02:00
2009-05-02 23:53:27 +02:00
#include "shell.h"
2009-05-02 23:03:37 +02:00
#include "callback.h"
#include "regs.h"
2009-05-02 23:53:27 +02:00
#include "../dos/drives.h"
2009-05-02 23:03:37 +02:00
static SHELL_Cmd cmd_list[]={
2009-05-02 23:43:00 +02:00
{ "CHDIR", 0, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"},
{ "CD", 1, &DOS_Shell::CMD_CHDIR, "SHELL_CMD_CHDIR_HELP"},
{ "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"},
{ "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"},
{ "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"},
{ "DEL", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
{ "DELETE", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
{ "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
{ "ECHO", 0, &DOS_Shell::CMD_ECHO, "SHELL_CMD_ECHO_HELP"},
{ "EXIT", 0, &DOS_Shell::CMD_EXIT, "SHELL_CMD_EXIT_HELP"},
2009-05-03 00:02:15 +02:00
{ "HELP", 1, &DOS_Shell::CMD_HELP, "SHELL_CMD_HELP_HELP"},
2009-05-02 23:43:00 +02:00
{ "MKDIR", 0, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"},
{ "MD", 1, &DOS_Shell::CMD_MKDIR, "SHELL_CMD_MKDIR_HELP"},
{ "RMDIR", 0, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"},
{ "RD", 1, &DOS_Shell::CMD_RMDIR, "SHELL_CMD_RMDIR_HELP"},
{ "SET", 0, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"},
{ "IF", 0, &DOS_Shell::CMD_IF, "SHELL_CMD_IF_HELP"},
{ "GOTO", 0, &DOS_Shell::CMD_GOTO, "SHELL_CMD_GOTO_HELP"},
{ "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"},
{ "REM", 0, &DOS_Shell::CMD_REM, "SHELL_CMD_REM_HELP"},
{ "RENAME", 0, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"},
{ "REN", 1, &DOS_Shell::CMD_RENAME, "SHELL_CMD_RENAME_HELP"},
{ "PAUSE", 0, &DOS_Shell::CMD_PAUSE, "SHELL_CMD_PAUSE_HELP"},
{ "CALL", 0, &DOS_Shell::CMD_CALL, "SHELL_CMD_CALL_HELP"},
2009-05-02 23:53:27 +02:00
{ "SUBST", 0, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"},
{ "LOADHIGH", 0, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"},
{ "LH", 1, &DOS_Shell::CMD_LOADHIGH, "SHELL_CMD_LOADHIGH_HELP"},
2009-05-03 00:02:15 +02:00
{ "CHOICE", 0, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"},
{ "ATTRIB", 0, &DOS_Shell::CMD_ATTRIB, "SHELL_CMD_ATTRIB_HELP"},
2009-05-02 23:53:27 +02:00
{0,0,0,0}
2009-05-02 23:03:37 +02:00
};
void DOS_Shell::DoCommand(char * line) {
/* First split the line into command and arguments */
line=trim(line);
2009-05-03 00:02:15 +02:00
char cmd[CMD_MAXLINE];
2009-05-02 23:03:37 +02:00
char * cmd_write=cmd;
while (*line) {
if (*line==32) break;
if (*line=='/') break;
2009-05-02 23:43:00 +02:00
if (*line=='\t') break;
if ((*line=='.') ||(*line =='\\')) { //allow stuff like cd.. and dir.exe cd\kees
*cmd_write=0;
Bit32u cmd_index=0;
while (cmd_list[cmd_index].name) {
if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) {
(this->*(cmd_list[cmd_index].handler))(line);
return;
}
cmd_index++;
}
}
2009-05-02 23:03:37 +02:00
*cmd_write++=*line++;
}
*cmd_write=0;
if (strlen(cmd)==0) return;
/* Check the internal list */
Bit32u cmd_index=0;
while (cmd_list[cmd_index].name) {
if (strcasecmp(cmd_list[cmd_index].name,cmd)==0) {
(this->*(cmd_list[cmd_index].handler))(line);
2009-05-02 23:20:05 +02:00
return;
2009-05-02 23:03:37 +02:00
}
cmd_index++;
}
/* This isn't an internal command execute it */
Execute(cmd,line);
}
void DOS_Shell::CMD_CLS(char * args) {
reg_ax=0x0003;
CALLBACK_RunRealInt(0x10);
};
2009-05-02 23:27:47 +02:00
void DOS_Shell::CMD_DELETE(char * args) {
2009-05-02 23:43:00 +02:00
2009-05-02 23:27:47 +02:00
char * rem=ScanCMDRemain(args);
if (rem) {
WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem);
return;
}
2009-05-02 23:43:00 +02:00
/* If delete accept switches mind the space infront of them. See the dir /p code */
2009-05-02 23:27:47 +02:00
char full[DOS_PATHLENGTH];
2009-05-02 23:43:00 +02:00
char buffer[CROSS_LEN];
args = ExpandDot(args,buffer);
StripSpaces(args);
2009-05-02 23:27:47 +02:00
if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; }
//TODO Maybe support confirmation for *.* like dos does.
2009-05-02 23:43:00 +02:00
bool res=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME);
2009-05-02 23:27:47 +02:00
if (!res) {
WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args);return;
}
//end can't be 0, but if it is we'll get a nice crash, who cares :)
char * end=strrchr(full,'\\')+1;*end=0;
char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u time,date;Bit8u attr;
2009-05-03 00:02:15 +02:00
DOS_DTA dta(dos.dta());
2009-05-02 23:27:47 +02:00
while (res) {
dta.GetResult(name,size,date,time,attr);
if (!(attr & (DOS_ATTR_DIRECTORY|DOS_ATTR_READ_ONLY))) {
strcpy(end,name);
if (!DOS_UnlinkFile(full)) WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),full);
}
res=DOS_FindNext();
}
}
2009-05-02 23:03:37 +02:00
void DOS_Shell::CMD_HELP(char * args){
/* Print the help */
WriteOut(MSG_Get("SHELL_CMD_HELP"));
Bit32u cmd_index=0;
while (cmd_list[cmd_index].name) {
2009-05-02 23:20:05 +02:00
if (!cmd_list[cmd_index].flags) WriteOut("%-8s %s",cmd_list[cmd_index].name,MSG_Get(cmd_list[cmd_index].help));
2009-05-02 23:03:37 +02:00
cmd_index++;
}
}
2009-05-02 23:27:47 +02:00
void DOS_Shell::CMD_RENAME(char * args){
2009-05-02 23:43:00 +02:00
StripSpaces(args);
if(!*args) {SyntaxError();return;}
if((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;}
2009-05-03 00:02:15 +02:00
char * arg1=StripWord(args);
DOS_Rename(arg1,args);
2009-05-02 23:27:47 +02:00
}
2009-05-02 23:43:00 +02:00
void DOS_Shell::CMD_ECHO(char * args){
2009-05-02 23:03:37 +02:00
if (!*args) {
if (echo) { WriteOut(MSG_Get("SHELL_CMD_ECHO_ON"));}
else { WriteOut(MSG_Get("SHELL_CMD_ECHO_OFF"));}
2009-05-02 23:43:00 +02:00
return;
2009-05-02 23:03:37 +02:00
}
2009-05-02 23:43:00 +02:00
char buffer[512];
char* pbuffer = buffer;
strcpy(buffer,args);
StripSpaces(pbuffer);
if (strcasecmp(pbuffer,"OFF")==0) {
2009-05-02 23:03:37 +02:00
echo=false;
return;
}
2009-05-02 23:43:00 +02:00
if (strcasecmp(pbuffer,"ON")==0) {
2009-05-02 23:03:37 +02:00
echo=true;
return;
}
2009-05-02 23:43:00 +02:00
args++;//skip first character. either a slash or dot or space
2009-05-02 23:03:37 +02:00
WriteOut("%s\n",args);
};
2009-05-02 23:43:00 +02:00
2009-05-02 23:03:37 +02:00
void DOS_Shell::CMD_EXIT(char * args) {
exit=true;
};
void DOS_Shell::CMD_CHDIR(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:03:37 +02:00
if (!*args) {
Bit8u drive=DOS_GetDefaultDrive()+'A';
2009-05-02 23:12:18 +02:00
char dir[DOS_PATHLENGTH];
2009-05-02 23:03:37 +02:00
DOS_GetCurrentDir(0,dir);
WriteOut("%c:\\%s\n",drive,dir);
2009-05-03 00:02:15 +02:00
} else if (!DOS_ChangeDir(args)) {
WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args);
2009-05-02 23:03:37 +02:00
}
};
void DOS_Shell::CMD_MKDIR(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:03:37 +02:00
char * rem=ScanCMDRemain(args);
if (rem) {
WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem);
return;
}
if (!DOS_MakeDir(args)) {
WriteOut(MSG_Get("SHELL_CMD_MKDIR_ERROR"),args);
}
};
void DOS_Shell::CMD_RMDIR(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:03:37 +02:00
char * rem=ScanCMDRemain(args);
if (rem) {
WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem);
return;
}
if (!DOS_RemoveDir(args)) {
WriteOut(MSG_Get("SHELL_CMD_RMDIR_ERROR"),args);
}
};
2009-05-02 23:20:05 +02:00
static void FormatNumber(Bitu num,char * buf) {
Bitu numm,numk,numb;
2009-05-02 23:03:37 +02:00
numb=num % 1000;
num/=1000;
numk=num % 1000;
num/=1000;
numm=num;
if (numm) {
sprintf(buf,"%d,%03d,%03d",numm,numk,numb);
return;
};
if (numk) {
sprintf(buf,"%d,%03d",numk,numb);
return;
};
sprintf(buf,"%d",numb);
}
void DOS_Shell::CMD_DIR(char * args) {
char numformat[16];
char path[DOS_PATHLENGTH];
2009-05-03 00:02:15 +02:00
std::string line;
if(GetEnvStr("DIRCMD",line)){
std::string::size_type idx = line.find('=');
std::string value=line.substr(idx +1 , std::string::npos);
line = std::string(args) + " " + value;
args=const_cast<char*>(line.c_str());
}
2009-05-02 23:03:37 +02:00
bool optW=ScanCMDBool(args,"W");
bool optS=ScanCMDBool(args,"S");
bool optP=ScanCMDBool(args,"P");
2009-05-03 00:02:15 +02:00
bool optAD=ScanCMDBool(args,"AD");
2009-05-02 23:03:37 +02:00
char * rem=ScanCMDRemain(args);
if (rem) {
WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem);
return;
}
Bit32u byte_count,file_count,dir_count;
2009-05-02 23:43:00 +02:00
Bitu w_count=0;
Bitu p_count=0;
Bitu w_size = optW?5:1;
2009-05-02 23:03:37 +02:00
byte_count=file_count=dir_count=0;
2009-05-02 23:43:00 +02:00
char buffer[CROSS_LEN];
2009-05-02 23:53:27 +02:00
args = trim(args);
Bit32u argLen = strlen(args);
if (argLen == 0) {
strcpy(args,"*.*"); //no arguments.
} else {
switch (args[argLen-1])
{
case '\\': // handle \, C:\, etc.
case ':' : // handle C:, etc.
strcat(args,"*.*");
break;
default:
break;
}
}
2009-05-02 23:43:00 +02:00
args = ExpandDot(args,buffer);
2009-05-02 23:53:27 +02:00
if (!strrchr(args,'*') && !strrchr(args,'?')) {
Bit16u attribute=0;
if(DOS_GetFileAttr(args,&attribute) && (attribute&DOS_ATTR_DIRECTORY) ) {
strcat(args,"\\*.*"); // if no wildcard and a directory, get its files
}
}
if (!strrchr(args,'.')) {
strcat(args,".*"); // if no extension, get them all
}
2009-05-02 23:03:37 +02:00
/* Make a full path in the args */
2009-05-02 23:12:18 +02:00
if (!DOS_Canonicalize(args,path)) {
2009-05-02 23:43:00 +02:00
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
2009-05-02 23:03:37 +02:00
return;
}
*(strrchr(path,'\\')+1)=0;
WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path);
2009-05-03 00:02:15 +02:00
DOS_DTA dta(dos.dta());
2009-05-02 23:43:00 +02:00
bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME);
2009-05-02 23:03:37 +02:00
if (!ret) {
WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args);
return;
}
2009-05-03 00:02:15 +02:00
do { /* File name and extension */
2009-05-02 23:20:05 +02:00
char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
dta.GetResult(name,size,date,time,attr);
2009-05-03 00:02:15 +02:00
/* Skip non-directories if option AD is present */
if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue;
2009-05-02 23:03:37 +02:00
char * ext="";
2009-05-02 23:20:05 +02:00
if (!optW && (name[0] != '.')) {
ext = strrchr(name, '.');
2009-05-02 23:03:37 +02:00
if (!ext) ext = "";
else *ext++ = '\0';
2009-05-02 23:20:05 +02:00
}
Bit8u day = date & 0x001f;
Bit8u month = (date >> 5) & 0x000f;
Bit16u year = (date >> 9) + 1980;
Bit8u hour = (time >> 5 ) >> 6;
Bit8u minute = (time >> 5) & 0x003f;
2009-05-02 23:03:37 +02:00
/* output the file */
2009-05-02 23:20:05 +02:00
if (attr & DOS_ATTR_DIRECTORY) {
2009-05-02 23:03:37 +02:00
if (optW) {
2009-05-02 23:20:05 +02:00
WriteOut("[%s]",name);
for (Bitu i=14-strlen(name);i>0;i--) WriteOut(" ");
2009-05-02 23:03:37 +02:00
} else {
2009-05-02 23:20:05 +02:00
WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"<DIR>",day,month,year,hour,minute);
2009-05-02 23:03:37 +02:00
}
dir_count++;
} else {
if (optW) {
2009-05-02 23:20:05 +02:00
WriteOut("%-16s",name);
2009-05-02 23:03:37 +02:00
} else {
2009-05-02 23:20:05 +02:00
FormatNumber(size,numformat);
WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute);
2009-05-02 23:03:37 +02:00
}
file_count++;
2009-05-02 23:20:05 +02:00
byte_count+=size;
2009-05-02 23:03:37 +02:00
}
if (optW) {
w_count++;
}
2009-05-02 23:43:00 +02:00
if(optP) {
if(!(++p_count%(22*w_size))) {
CMD_PAUSE(args);
}
}
2009-05-03 00:02:15 +02:00
} while ( (ret=DOS_FindNext()) );
2009-05-02 23:03:37 +02:00
if (optW) {
if (w_count%5) WriteOut("\n");
}
2009-05-02 23:43:00 +02:00
2009-05-02 23:03:37 +02:00
/* Show the summary of results */
FormatNumber(byte_count,numformat);
WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat);
2009-05-02 23:20:05 +02:00
Bit8u drive=dta.GetSearchDrive();
2009-05-02 23:03:37 +02:00
//TODO Free Space
2009-05-02 23:20:05 +02:00
Bitu free_space=1024*1024*100;
if (Drives[drive]) {
2009-05-02 23:27:47 +02:00
Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters;
2009-05-02 23:20:05 +02:00
Drives[drive]->AllocationInfo(&bytes_sector,&sectors_cluster,&total_clusters,&free_clusters);
free_space=bytes_sector*sectors_cluster*free_clusters;
}
FormatNumber(free_space,numformat);
2009-05-02 23:03:37 +02:00
WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat);
}
void DOS_Shell::CMD_COPY(char * args) {
2009-05-03 00:02:15 +02:00
static char defaulttarget[] = ".";
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-03 00:02:15 +02:00
DOS_DTA dta(dos.dta());
2009-05-02 23:35:44 +02:00
Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
char name[DOS_NAMELENGTH_ASCII];
2009-05-03 00:02:15 +02:00
// ignore /b and /t switches: always copy binary
ScanCMDBool(args,"B");
ScanCMDBool(args,"T");
2009-05-02 23:03:37 +02:00
char * rem=ScanCMDRemain(args);
if (rem) {
WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem);
return;
}
2009-05-02 23:35:44 +02:00
// source/target
2009-05-03 00:02:15 +02:00
char* source = StripWord(args);
char* target = NULL;
if (args && *args) target = StripWord(args);
if (!target || !*target) target = defaulttarget;
2009-05-02 23:35:44 +02:00
// Target and Source have to be there
if (!source || !strlen(source)) {
WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args);
return;
};
/* Make a full path in the args */
char pathSource[DOS_PATHLENGTH];
char pathTarget[DOS_PATHLENGTH];
if (!DOS_Canonicalize(source,pathSource)) {
2009-05-02 23:43:00 +02:00
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
2009-05-02 23:35:44 +02:00
return;
}
// cut search pattern
char* pos = strrchr(pathSource,'\\');
if (pos) *(pos+1) = 0;
if (!DOS_Canonicalize(target,pathTarget)) {
2009-05-02 23:43:00 +02:00
WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));
2009-05-02 23:35:44 +02:00
return;
}
2009-05-02 23:43:00 +02:00
char* temp = strstr(pathTarget,"*.*");
if(temp) *temp = 0;//strip off *.* from target
// add '\\' if target is a directoy
2009-05-02 23:35:44 +02:00
if (pathTarget[strlen(pathTarget)-1]!='\\') {
2009-05-02 23:43:00 +02:00
if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) {
2009-05-02 23:35:44 +02:00
dta.GetResult(name,size,date,time,attr);
if (attr & DOS_ATTR_DIRECTORY)
strcat(pathTarget,"\\");
}
};
2009-05-03 00:02:15 +02:00
bool ret=DOS_FindFirst(source,0xffff & ~DOS_ATTR_VOLUME);
2009-05-02 23:35:44 +02:00
if (!ret) {
WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args);
return;
}
Bit32u count = 0;
Bit16u sourceHandle,targetHandle;
char nameTarget[DOS_PATHLENGTH];
char nameSource[DOS_PATHLENGTH];
while (ret) {
dta.GetResult(name,size,date,time,attr);
if ((attr & DOS_ATTR_DIRECTORY)==0) {
strcpy(nameSource,pathSource);
strcat(nameSource,name);
// Open Source
if (DOS_OpenFile(nameSource,0,&sourceHandle)) {
// Create Target
strcpy(nameTarget,pathTarget);
if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,name);
if (DOS_CreateFile(nameTarget,0,&targetHandle)) {
// Copy
Bit8u buffer[0x8000];
bool failed = false;
Bit16u toread = 0x8000;
do {
failed |= DOS_ReadFile(sourceHandle,buffer,&toread);
failed |= DOS_WriteFile(targetHandle,buffer,&toread);
} while (toread==0x8000);
failed |= DOS_CloseFile(sourceHandle);
failed |= DOS_CloseFile(targetHandle);
WriteOut(" %s\n",name);
count++;
} else {
DOS_CloseFile(sourceHandle);
WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),target);
}
} else WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),source);
};
ret=DOS_FindNext();
};
WriteOut(MSG_Get("SHELL_CMD_COPY_SUCCESS"),count);
2009-05-02 23:03:37 +02:00
}
void DOS_Shell::CMD_SET(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:20:05 +02:00
std::string line;
2009-05-02 23:03:37 +02:00
if (!*args) {
/* No command line show all environment lines */
2009-05-02 23:20:05 +02:00
Bitu count=GetEnvCount();
for (Bitu a=0;a<count;a++) {
if (GetEnvNum(a,line)) WriteOut("%s\n",line.c_str());
2009-05-02 23:03:37 +02:00
}
return;
}
char * p=strpbrk(args, "=");
if (!p) {
2009-05-02 23:20:05 +02:00
if (!GetEnvStr(args,line)) WriteOut(MSG_Get("SHELL_CMD_SET_NOT_SET"),args);
WriteOut("%s\n",line.c_str());
2009-05-02 23:03:37 +02:00
} else {
*p++=0;
if (!SetEnv(args,p)) {
WriteOut(MSG_Get("SHELL_CMD_SET_OUT_OF_SPACE"));
}
}
}
void DOS_Shell::CMD_IF(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:03:37 +02:00
bool has_not=false;
char * comp=strchr(args,'=');
if (comp) {
if (comp[1]!='=') {SyntaxError();return;}
*comp++=' ';
*comp++=' ';
};
2009-05-03 00:02:15 +02:00
char * word=StripWord(args);
2009-05-02 23:03:37 +02:00
if (strcasecmp(word,"NOT")==0) {
2009-05-03 00:02:15 +02:00
word=StripWord(args);
2009-05-02 23:03:37 +02:00
has_not=true;
}
if (strcasecmp(word,"EXIST")==0) {
2009-05-03 00:02:15 +02:00
word=StripWord(args);
2009-05-02 23:03:37 +02:00
if (!*word) {
WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME"));
return;
};
2009-05-03 00:02:15 +02:00
if (DOS_FindFirst(word,0xffff & ~DOS_ATTR_VOLUME)==(!has_not)) DoCommand(args);
2009-05-02 23:03:37 +02:00
return;
}
if (strcasecmp(word,"ERRORLEVEL")==0) {
2009-05-03 00:02:15 +02:00
word=StripWord(args);
2009-05-02 23:03:37 +02:00
if(!isdigit(*word)) {
WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER"));
return;
}
Bit8u n=0;
do n = n * 10 + (*word - '0');
while (isdigit(*++word));
if(*word && !isspace(*word)) {
WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER"));
return;
}
/* Read the error code from DOS */
2009-05-02 23:43:00 +02:00
if ((dos.return_code>=n) ==(!has_not)) DoCommand(args);
2009-05-02 23:03:37 +02:00
return;
}
/* Normal if string compare */
if (!*args) { SyntaxError();return;};
2009-05-03 00:02:15 +02:00
char * word2=StripWord(args);
2009-05-02 23:03:37 +02:00
if ((strcmp(word,word2)==0)==(!has_not)) DoCommand(args);
}
void DOS_Shell::CMD_GOTO(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:03:37 +02:00
if (!bf) return;
2009-05-02 23:43:00 +02:00
if (*args &&(*args==':')) args++;
2009-05-02 23:03:37 +02:00
if (!*args) {
WriteOut(MSG_Get("SHELL_CMD_GOTO_MISSING_LABEL"));
return;
}
if (!bf->Goto(args)) {
WriteOut(MSG_Get("SHELL_CMD_GOTO_LABEL_NOT_FOUND"),args);
return;
}
}
void DOS_Shell::CMD_TYPE(char * args) {
2009-05-02 23:43:00 +02:00
StripSpaces(args);
2009-05-02 23:03:37 +02:00
if (!*args) {
WriteOut(MSG_Get("SHELL_SYNTAXERROR"));
return;
}
Bit16u handle;
char * word;
nextfile:
2009-05-03 00:02:15 +02:00
word=StripWord(args);
2009-05-02 23:03:37 +02:00
if (!DOS_OpenFile(word,0,&handle)) {
WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),word);
return;
}
Bit16u n;Bit8u c;
do {
n=1;
DOS_ReadFile(handle,&c,&n);
DOS_WriteFile(STDOUT,&c,&n);
} while (n);
DOS_CloseFile(handle);
if (*args) goto nextfile;
}
2009-05-02 23:20:05 +02:00
void DOS_Shell::CMD_REM(char * args) {
}
2009-05-02 23:03:37 +02:00
2009-05-02 23:35:44 +02:00
void DOS_Shell::CMD_PAUSE(char * args){
2009-05-02 23:43:00 +02:00
WriteOut(MSG_Get("SHELL_CMD_PAUSE"));
Bit8u c;Bit16u n=1;
2009-05-02 23:35:44 +02:00
DOS_ReadFile (STDIN,&c,&n);
}
2009-05-02 23:27:47 +02:00
2009-05-02 23:43:00 +02:00
void DOS_Shell::CMD_CALL(char * args){
this->call=true; /* else the old batchfile will be closed first */
this->ParseLine(args);
this->call=false;
}
2009-05-02 23:53:27 +02:00
void DOS_Shell::CMD_SUBST (char * args) {
/* If more that one type can be substed think of something else
* E.g. make basedir member dos_drive instead of localdrive
*/
localDrive* ldp=0;
char mountstring[DOS_PATHLENGTH+CROSS_LEN+20];
char temp_str[2] = { 0,0 };
try {
strcpy(mountstring,"MOUNT ");
StripSpaces(args);
std::string arg;
CommandLine command(0,args);
if (command.GetCount() != 2) throw 0 ;
command.FindCommand(2,arg);
if((arg=="/D" ) || (arg=="/d")) throw 1; //No removal (one day)
command.FindCommand(1,arg);
if(arg[1] !=':') throw(0);
temp_str[0]=toupper(args[0]);
if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use
strcat(mountstring,temp_str);
strcat(mountstring," ");
command.FindCommand(2,arg);
Bit8u drive;char fulldir[DOS_PATHLENGTH];
if (!DOS_MakeName(const_cast<char*>(arg.c_str()),fulldir,&drive)) throw 0;
if( ( ldp=dynamic_cast<localDrive*>(Drives[drive])) == 0 ) throw 0;
char newname[CROSS_LEN];
2009-05-03 00:02:15 +02:00
strcpy(newname, ldp->basedir);
2009-05-02 23:53:27 +02:00
strcat(newname,fulldir);
CROSS_FILENAME(newname);
ldp->dirCache.ExpandName(newname);
2009-05-03 00:02:15 +02:00
strcat(mountstring,"\"");
2009-05-02 23:53:27 +02:00
strcat(mountstring, newname);
2009-05-03 00:02:15 +02:00
strcat(mountstring,"\"");
2009-05-02 23:53:27 +02:00
this->ParseLine(mountstring);
}
catch(int a){
if(a == 0) {
WriteOut(MSG_Get("SHELL_CMD_SUBST_FAILURE"));
} else {
WriteOut(MSG_Get("SHELL_CMD_SUBST_NO_REMOVE"));
}
return;
}
2009-05-03 00:02:15 +02:00
catch(...) { //dynamic cast failed =>so no localdrive
WriteOut(MSG_Get("SHELL_CMD_SUBST_FAILURE"));
return;
}
2009-05-02 23:53:27 +02:00
return;
}
void DOS_Shell::CMD_LOADHIGH(char *args){
this->ParseLine(args);
}
2009-05-03 00:02:15 +02:00
void DOS_Shell::CMD_CHOICE(char * args){
static char defargs[] = "[YN]";
static char defchoice[] = "yn";
char *rem = NULL, *ptr;
bool optN = false;
if (args) {
char *last = strchr(args,0);
StripSpaces(args);
optN=ScanCMDBool(args,"N");
rem=ScanCMDRemain(args);
if (rem && *rem && (tolower(rem[1]) != 'c' || rem[2] != ':')) {
WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem);
return;
}
if (args == rem) args = strchr(rem,0)+1;
if (rem) rem += 3;
if (args > last) args = NULL;
}
if (!args || !*args) args = defargs;
if (!rem || !*rem) rem = defchoice;
ptr = rem;
Bit8u c;
while ((c = *ptr)) *ptr++ = tolower(c);
WriteOut(args);
if (!optN) WriteOut("\r\n");
Bit16u n=1;
do {
DOS_ReadFile (STDIN,&c,&n);
} while (!c || !(ptr = strchr(rem,tolower(c))));
if (optN) {
DOS_WriteFile (STDOUT,&c, &n);
WriteOut("\r\n");
}
dos.return_code = ptr-rem+1;
}
void DOS_Shell::CMD_ATTRIB(char *args){
// No-Op for now.
}