void DOS_Shell::CMD_DELETE(char * args) { HELP("DELETE"); /* Command uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } /* If delete accept switches mind the space infront of them. See the dir /p code */ char full[DOS_PATHLENGTH],sfull[DOS_PATHLENGTH+2]; char buffer[CROSS_LEN]; args = ExpandDot(args,buffer); StripSpaces(args); if (!DOS_Canonicalize(args,full)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH"));return; } //TODO Maybe support confirmation for *.* like dos does. char spath[DOS_PATHLENGTH],sargs[DOS_PATHLENGTH]; if (!DOS_GetSFNPath(args,spath,false)) { WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args); return; } sprintf(sargs,"\"%s\"",spath); bool res=DOS_FindFirst(sargs,0xffff & ~DOS_ATTR_VOLUME); if (!res) { WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),args); dos.dta(save_dta); 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],lname[LFN_NAMELENGTH+1]; Bit32u size;Bit16u time,date;Bit8u attr; DOS_DTA dta(dos.dta()); while (res) { dta.GetResult(name,lname,size,date,time,attr); if (!(attr & (DOS_ATTR_DIRECTORY|DOS_ATTR_READ_ONLY))) { strcpy(end,name); strcpy(sfull,full); if (uselfn) sprintf(sfull,"\"%s\"",full); if (!DOS_UnlinkFile(sfull)) WriteOut(MSG_Get("SHELL_CMD_DEL_ERROR"),full); } res=DOS_FindNext(); } dos.dta(save_dta); }
void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE] = {0}; std::string line; if (cmd->FindStringRemainBegin("/C",line)) { strcpy(input_line,line.c_str()); char* sep = strpbrk(input_line,"\r\n"); //GTA installer if (sep) *sep = 0; DOS_Shell temp; temp.echo = echo; temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; temp.RunInternal(); // exits when no bf is found. return; } /* Start a normal shell and check for a first command init */ WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); #if C_DEBUG WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); WriteOut(MSG_Get("SHELL_STARTUP_END")); if (cmd->FindString("/INIT",line,true)) { strcpy(input_line,line.c_str()); line.erase(); ParseLine(input_line); } do { if (bf){ if(bf->ReadLine(input_line)) { if (echo) { if (input_line[0]!='@') { ShowPrompt(); WriteOut_NoParsing(input_line); WriteOut_NoParsing("\n"); }; }; ParseLine(input_line); if (echo) WriteOut("\n"); } } else { if (echo) ShowPrompt(); InputCommand(input_line); ParseLine(input_line); if (echo && !bf) WriteOut_NoParsing("\n"); } } while (!exit); }
bool securemode_check() { if (control->SecureMode()) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); return true; } return false; }
void DOS_Shell::CMD_PAUSE(char * args){ HELP("PAUSE"); WriteOut(MSG_Get("SHELL_CMD_PAUSE")); Bit8u c;Bit16u n=1; DOS_ReadFile(STDIN,&c,&n); if (c==0) DOS_ReadFile(STDIN,&c,&n); // read extended key }
BOOL MSG_Init (PSZ MsgFile) { CHAR TempBuffer[1024]; MSG_Filename = MsgFile; if (MSG_Get(TempBuffer, 1024, 0)) return TRUE; printf ("%s not found, execution aborted.\n", MSG_Filename); return FALSE; }
void DOS_Shell::CMD_CHDIR(char * args) { HELP("CHDIR"); StripSpaces(args); char sargs[CROSS_LEN]; if (*args && !DOS_GetSFNPath(args,sargs,false)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } Bit8u drive = DOS_GetDefaultDrive()+'A'; char dir[DOS_PATHLENGTH]; if (!*args) { DOS_GetCurrentDir(0,dir,true); WriteOut("%c:\\%s\n",drive,dir); } else if(strlen(args) == 2 && args[1]==':') { Bit8u targetdrive = (args[0] | 0x20)-'a' + 1; unsigned char targetdisplay = *reinterpret_cast<unsigned char*>(&args[0]); if(!DOS_GetCurrentDir(targetdrive,dir,true)) { if(drive == 'Z') { WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(targetdisplay)); } else { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); } return; } WriteOut("%c:\\%s\n",toupper(targetdisplay),dir); if(drive == 'Z') WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT"),toupper(targetdisplay)); } else if (!DOS_ChangeDir(sargs)) { /* Changedir failed. Check if the filename is longer then 8 and/or contains spaces */ std::string temps(args),slashpart; std::string::size_type separator = temps.find_first_of("\\/"); if(!separator) { slashpart = temps.substr(0,1); temps.erase(0,1); } separator = temps.find_first_of("\\/"); if(separator != std::string::npos) temps.erase(separator); separator = temps.find_first_of("\""); if(separator != std::string::npos) temps.erase(separator); separator = temps.rfind('.'); if(separator != std::string::npos) temps.erase(separator); separator = temps.find(' '); if(separator != std::string::npos) {/* Contains spaces */ temps.erase(separator); if(temps.size() >6) temps.erase(6); temps += "~1"; WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_2"),temps.insert(0,slashpart).c_str()); } else { if (drive == 'Z') { WriteOut(MSG_Get("SHELL_CMD_CHDIR_HINT_3")); } else { WriteOut(MSG_Get("SHELL_CMD_CHDIR_ERROR"),args); } } } }
void DOS_Shell::CMD_GOTO(char * args) { HELP("GOTO"); StripSpaces(args); if (!bf) return; if (*args &&(*args==':')) args++; //label ends at the first space char* non_space = args; while (*non_space) { if((*non_space == ' ') || (*non_space == '\t')) *non_space = 0; else non_space++; } 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_CHOICE(char * args){ HELP("CHOICE"); static char defchoice[3] = {'y','n',0}; char *rem = NULL, *ptr; bool optN = ScanCMDBool(args,"N"); bool optS = ScanCMDBool(args,"S"); //Case-sensitive matching ScanCMDBool(args,"T"); //Default Choice after timeout if (args) { char *last = strchr(args,0); StripSpaces(args); rem = ScanCMDRemain(args); if (rem && *rem && (tolower(rem[1]) != 'c')) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } if (args == rem) args = strchr(rem,0)+1; if (rem) rem += 2; if(rem && rem[0]==':') rem++; /* optional : after /c */ if (args > last) args = NULL; } if (!rem || !*rem) rem = defchoice; /* No choices specified use YN */ ptr = rem; Bit8u c; if(!optS) while ((c = *ptr)) *ptr++ = (char)toupper(c); /* When in no case-sensitive mode. make everything upcase */ if(args && *args ) { StripSpaces(args); size_t argslen = strlen(args); if(argslen>1 && args[0] == '"' && args[argslen-1] =='"') { args[argslen-1] = 0; //Remove quotes args++; } WriteOut(args); } /* Show question prompt of the form [a,b]? where a b are the choice values */ if (!optN) { if(args && *args) WriteOut(" "); WriteOut("["); size_t len = strlen(rem); for(size_t t = 1; t < len; t++) { WriteOut("%c,",rem[t-1]); } WriteOut("%c]?",rem[len-1]); } Bit16u n=1; do { DOS_ReadFile (STDIN,&c,&n); } while (!c || !(ptr = strchr(rem,(optS?c:toupper(c))))); c = optS?c:(Bit8u)toupper(c); DOS_WriteFile (STDOUT,&c, &n); dos.return_code = (Bit8u)(ptr-rem+1); }
void DOS_Shell::CMD_RENAME(char * args){ HELP("RENAME"); StripSpaces(args); if (!*args) {SyntaxError();return;} if ((strchr(args,'*')!=NULL) || (strchr(args,'?')!=NULL) ) { WriteOut(MSG_Get("SHELL_CMD_NO_WILD"));return;} char * arg1=StripArg(args); StripSpaces(args); if (!*args) {SyntaxError();return;} char* slash = strrchr(arg1,'\\'); if (slash) { /* If directory specified (crystal caves installer) * rename from c:\X : rename c:\abc.exe abc.shr. * File must appear in C:\ * Ren X:\A\B C => ren X:\A\B X:\A\C */ char dir_source[DOS_PATHLENGTH + 4] = {0}; //not sure if drive portion is included in pathlength //Copy first and then modify, makes GCC happy safe_strncpy(dir_source,arg1,DOS_PATHLENGTH + 4); char* dummy = strrchr(dir_source,'\\'); if (!dummy) { //Possible due to length WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } dummy++; *dummy = 0; //Maybe check args for directory, as I think that isn't allowed //dir_source and target are introduced for when we support multiple files being renamed. char target[DOS_PATHLENGTH+CROSS_LEN + 5] = {0}; strcpy(target,dir_source); strncat(target,args,CROSS_LEN); DOS_Rename(arg1,target); } else { DOS_Rename(arg1,args); } }
void DOS_Shell::CMD_VER(char *args) { HELP("VER"); if(args && *args) { char* word = StripWord(args); if(strcasecmp(word,"set")) return; word = StripWord(args); if (!*args && !*word) { //Reset dos.version.major = 7; dos.version.minor = 10; } else if (*args == 0 && *word && (strchr(word,'.') != 0)) { //Allow: ver set 7.10 const char * p = strchr(word,'.'); dos.version.major = (Bit8u)(atoi(word)); dos.version.minor = (Bit8u)(atoi(p+1)); } else { //Official syntax: ver set 7 10 dos.version.major = (Bit8u)(atoi(word)); dos.version.minor = (Bit8u)(atoi(args)); } if (autolfn) uselfn=dos.version.major>=7; } else WriteOut(MSG_Get("SHELL_CMD_VER_VER"),VERSION,dos.version.major,dos.version.minor,uselfn?"enabled":"disabled"); }
void DOS_Shell::DoCommand(char * line) { /* First split the line into command and arguments */ line=trim(line); char cmd_buffer[CMD_MAXLINE]; char * cmd_write=cmd_buffer; while (*line) { if (*line == 32) break; if (*line == '/') break; if (*line == '\t') break; if (*line == '=') break; // if (*line == ':') break; //This breaks drive switching as that is handled at a later stage. 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_buffer)==0) { (this->*(cmd_list[cmd_index].handler))(line); return; } cmd_index++; } } *cmd_write++=*line++; } *cmd_write=0; if (strlen(cmd_buffer)==0) return; /* Check the internal list */ Bit32u cmd_index=0; while (cmd_list[cmd_index].name) { if (strcasecmp(cmd_list[cmd_index].name,cmd_buffer)==0) { (this->*(cmd_list[cmd_index].handler))(line); return; } cmd_index++; } /* This isn't an internal command execute it */ if(Execute(cmd_buffer,line)) return; if(CheckConfig(cmd_buffer,line)) return; WriteOut(MSG_Get("SHELL_EXECUTE_ILLEGAL_COMMAND"),cmd_buffer); }
void DOS_Shell::CMD_TIME(char * args) { HELP("TIME"); if(ScanCMDBool(args,"H")) { // synchronize time with host parameter time_t curtime; struct tm *loctime; curtime = time (NULL); loctime = localtime (&curtime); //reg_cx = loctime->; //reg_dh = loctime->; //reg_dl = loctime->; // reg_ah=0x2d; // set system time TODO // CALLBACK_RunRealInt(0x21); Bit32u ticks=(Bit32u)(((double)(loctime->tm_hour*3600+ loctime->tm_min*60+ loctime->tm_sec))*18.206481481); mem_writed(BIOS_TIMER,ticks); return; } bool timeonly = ScanCMDBool(args,"T"); reg_ah=0x2c; // get system time CALLBACK_RunRealInt(0x21); /* reg_dl= // 1/100 seconds reg_dh= // seconds reg_cl= // minutes reg_ch= // hours */ if(timeonly) { WriteOut("%2u:%02u\n",reg_ch,reg_cl); } else { WriteOut(MSG_Get("SHELL_CMD_TIME_NOW")); WriteOut("%2u:%02u:%02u,%02u\n",reg_ch,reg_cl,reg_dh,reg_dl); } };
void DOS_Shell::CMD_DIR(char * args) { HELP("DIR"); char numformat[16]; char path[DOS_PATHLENGTH]; char sargs[CROSS_LEN]; 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()); } bool optW=ScanCMDBool(args,"W"); ScanCMDBool(args,"S"); bool optP=ScanCMDBool(args,"P"); if (ScanCMDBool(args,"WP") || ScanCMDBool(args,"PW")) { optW=optP=true; } bool optB=ScanCMDBool(args,"B"); bool optAD=ScanCMDBool(args,"AD"); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); return; } Bit32u byte_count,file_count,dir_count; Bitu w_count=0; Bitu p_count=0; Bitu w_size = optW?5:1; byte_count=file_count=dir_count=0; char buffer[CROSS_LEN]; args = trim(args); size_t 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; } } args = ExpandDot(args,buffer); if (!strrchr(args,'*') && !strrchr(args,'?')) { Bit16u attribute=0; if(!DOS_GetSFNPath(args,sargs,false)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } if(DOS_GetFileAttr(sargs,&attribute) && (attribute&DOS_ATTR_DIRECTORY) ) { DOS_FindFirst(sargs,0xffff & ~DOS_ATTR_VOLUME); DOS_DTA dta(dos.dta()); strcpy(args,sargs); strcat(args,"\\*.*"); // if no wildcard and a directory, get its files } } if (!DOS_GetSFNPath(args,sargs,false)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } sprintf(args,"\"%s\"",sargs); if (!strrchr(args,'.')) { strcat(args,".*"); // if no extension, get them all } /* Make a full path in the args */ if (!DOS_Canonicalize(args,path)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } *(strrchr(path,'\\')+1)=0; if (!DOS_GetSFNPath(path,sargs,true)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); return; } if (*(sargs+strlen(sargs)-1) != '\\') strcat(sargs,"\\"); if (!optB) WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),sargs); /* Command uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); DOS_DTA dta(dos.dta()); bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { if (!optB) WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); dos.dta(save_dta); return; } do { /* File name and extension */ char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH+1]; Bit32u size;Bit16u date;Bit16u time;Bit8u attr; dta.GetResult(name,lname,size,date,time,attr); /* Skip non-directories if option AD is present */ if(optAD && !(attr&DOS_ATTR_DIRECTORY) ) continue; /* output the file */ if (optB) { // this overrides pretty much everything if (strcmp(".",uselfn?lname:name) && strcmp("..",uselfn?lname:name)) { WriteOut("%s\n",uselfn?lname:name); } } else { char * ext = empty_string; if (!optW && (name[0] != '.')) { ext = strrchr(name, '.'); if (!ext) ext = empty_string; else *ext++ = 0; } Bit8u day = (Bit8u)(date & 0x001f); Bit8u month = (Bit8u)((date >> 5) & 0x000f); Bit16u year = (Bit16u)((date >> 9) + 1980); Bit8u hour = (Bit8u)((time >> 5 ) >> 6); Bit8u minute = (Bit8u)((time >> 5) & 0x003f); if (attr & DOS_ATTR_DIRECTORY) { if (optW) { WriteOut("[%s]",name); size_t namelen = strlen(name); if (namelen <= 14) { for (size_t i=14-namelen;i>0;i--) WriteOut(" "); } } else { WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d %s\n",name,ext,"<DIR>",day,month,year,hour,minute,uselfn?lname:""); } dir_count++; } else { if (optW) { WriteOut("%-16s",name); } else { FormatNumber(size,numformat); WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d %s\n",name,ext,numformat,day,month,year,hour,minute,uselfn?lname:""); } file_count++; byte_count+=size; } if (optW) { w_count++; } } if (optP && !(++p_count%(22*w_size))) { CMD_PAUSE(empty_string); } } while ( (ret=DOS_FindNext()) ); if (optW) { if (w_count%5) WriteOut("\n"); } if (!optB) { /* Show the summary of results */ FormatNumber(byte_count,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat); Bit8u drive=dta.GetSearchDrive(); //TODO Free Space Bitu free_space=1024*1024*100; if (Drives[drive]) { Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters; Drives[drive]->AllocationInfo(&bytes_sector,§ors_cluster,&total_clusters,&free_clusters); free_space=bytes_sector*sectors_cluster*free_clusters; } FormatNumber(free_space,numformat); WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat); } dos.dta(save_dta); }
void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE] = {0}; std::string line; if (cmd->FindStringRemain("/C",line)) { strcpy(input_line,line.c_str()); char* sep = strpbrk(input_line,"\r\n"); //GTA installer if (sep) *sep = 0; DOS_Shell temp; temp.echo = echo; temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; temp.RunInternal(); // exits when no bf is found. return; } /* Start a normal shell and check for a first command init */ //--Modified 2012-08-19 by Alun Bestor to allow selective overriding of the startup messages. if (boxer_shouldDisplayStartupMessages()) { WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); #if C_DEBUG WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); WriteOut(MSG_Get("SHELL_STARTUP_END")); } //--End of modifications if (cmd->FindString("/INIT",line,true)) { //--Added 2009-12-13 by Alun Bestor to let Boxer monitor the autoexec process boxer_autoexecDidStart(); strcpy(input_line,line.c_str()); line.erase(); ParseLine(input_line); boxer_autoexecDidFinish(); //--End of modifications } do { //--Added 2012-08-19 by Alun Bestor to let Boxer insert its own commands into batch processing. if (boxer_hasPendingCommands()) { boxer_executeNextPendingCommand(); } else if (bf){ //--End of modifications if(bf->ReadLine(input_line)) { if (echo) { if (input_line[0]!='@') { ShowPrompt(); WriteOut_NoParsing(input_line); WriteOut_NoParsing("\n"); }; }; ParseLine(input_line); if (echo) WriteOut("\n"); } } else { //--Added 2009-11-29 by Alun Bestor as a hook for detecting when control has returned to the DOS prompt. boxer_didReturnToShell(); //--End of modifications if (echo) ShowPrompt(); InputCommand(input_line); //--Added 2012-08-19 by Alun Bestor to let Boxer interrupt the command input with its own commands. if (boxer_shellShouldContinue() && !boxer_hasPendingCommands()) { //--End of modifications ParseLine(input_line); if (echo && !bf) WriteOut_NoParsing("\n"); } } } while (boxer_shellShouldContinue() && !exit); }
bool DOS_Shell::Execute(char * name,char * args) { /* return true => don't check for hardware changes in do_command * return false => check for hardware changes in do_command */ char fullname[DOS_PATHLENGTH+4]; //stores results from Which char* p_fullname; char line[CMD_MAXLINE]; if(strlen(args)!= 0){ if(*args != ' '){ //put a space in front line[0]=' ';line[1]=0; strncat(line,args,CMD_MAXLINE-2); line[CMD_MAXLINE-1]=0; } else { safe_strncpy(line,args,CMD_MAXLINE); } }else{ line[0]=0; }; /* check for a drive change */ if (((strcmp(name + 1, ":") == 0) || (strcmp(name + 1, ":\\") == 0)) && isalpha(*name)) { if (!DOS_SetDrive(toupper(name[0])-'A')) { WriteOut(MSG_Get("SHELL_EXECUTE_DRIVE_NOT_FOUND"),toupper(name[0])); } return true; } /* Check for a full name */ p_fullname = Which(name); if (!p_fullname) return false; strcpy(fullname,p_fullname); const char* extension = strrchr(fullname,'.'); __android_log_print(ANDROID_LOG_INFO, "dosbox", "command fullname:%s", fullname); /*always disallow files without extension from being executed. */ /*only internal commands can be run this way and they never get in this handler */ if(extension == 0) { //Check if the result will fit in the parameters. Else abort if(strlen(fullname) >( DOS_PATHLENGTH - 1) ) return false; char temp_name[DOS_PATHLENGTH+4],* temp_fullname; //try to add .com, .exe and .bat extensions to filename strcpy(temp_name,fullname); strcat(temp_name,".COM"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".com";strcpy(fullname,temp_fullname); } else { strcpy(temp_name,fullname); strcat(temp_name,".EXE"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".exe";strcpy(fullname,temp_fullname);} else { strcpy(temp_name,fullname); strcat(temp_name,".BAT"); temp_fullname=Which(temp_name); if (temp_fullname) { extension=".bat";strcpy(fullname,temp_fullname);} else { return false; } } } } if (strcasecmp(extension, ".bat") == 0) { /* Run the .bat file */ /* delete old batch file if call is not active*/ bool temp_echo=echo; /*keep the current echostate (as delete bf might change it )*/ if(bf && !call) delete bf; bf=new BatchFile(this,fullname,name,line); echo=temp_echo; //restore it. } else { /* only .bat .exe .com extensions maybe be executed by the shell */ if(strcasecmp(extension, ".com") !=0) { if(strcasecmp(extension, ".exe") !=0) return false; } /* Run the .exe or .com file from the shell */ /* Allocate some stack space for tables in physical memory */ reg_sp-=0x200; //Add Parameter block DOS_ParamBlock block(SegPhys(ss)+reg_sp); block.Clear(); //Add a filename RealPt file_name=RealMakeSeg(ss,reg_sp+0x20); MEM_BlockWrite(Real2Phys(file_name),fullname,(Bitu)(strlen(fullname)+1)); /* HACK: Store full commandline for mount and imgmount */ full_arguments.assign(line); /* Fill the command line */ CommandTail cmdtail; cmdtail.count = 0; memset(&cmdtail.buffer,0,126); //Else some part of the string is unitialized (valgrind) if (strlen(line)>126) line[126]=0; cmdtail.count=(Bit8u)strlen(line); memcpy(cmdtail.buffer,line,strlen(line)); cmdtail.buffer[strlen(line)]=0xd; /* Copy command line in stack block too */ MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmdtail,128); /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; FCB_Parsename(dos.psp(),0x5C,0x00,cmdtail.buffer,&add); FCB_Parsename(dos.psp(),0x6C,0x00,&cmdtail.buffer[add],&add); block.exec.fcb1=RealMake(dos.psp(),0x5C); block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData(); #if 0 /* Save CS:IP to some point where i can return them from */ Bit32u oldeip=reg_eip; Bit16u oldcs=SegValue(cs); RealPt newcsip=CALLBACK_RealPointer(call_shellstop); SegSet16(cs,RealSeg(newcsip)); reg_ip=RealOff(newcsip); #endif /* Start up a dos execute interrupt */ reg_ax=0x4b00; //Filename pointer SegSet16(ds,SegValue(ss)); reg_dx=RealOff(file_name); //Paramblock SegSet16(es,SegValue(ss)); reg_bx=reg_sp; SETFLAGBIT(IF,false); CALLBACK_RunRealInt(0x21); /* Restore CS:IP and the stack */ reg_sp+=0x200; #if 0 reg_eip=oldeip; SegSet16(cs,oldcs); #endif } return true; //Executable started }
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 */ HELP("SUBST"); 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(1,arg); if( (arg.size()>1) && arg[1] !=':') throw(0); temp_str[0]=(char)toupper(args[0]); command.FindCommand(2,arg); if((arg=="/D") || (arg=="/d")) { if(!Drives[temp_str[0]-'A'] ) throw 1; //targetdrive not in use strcat(mountstring,"-u "); strcat(mountstring,temp_str); this->ParseLine(mountstring); return; } if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use strcat(mountstring,temp_str); strcat(mountstring," "); Bit8u drive;char dir[DOS_PATHLENGTH+2],fulldir[DOS_PATHLENGTH]; if (strchr(arg.c_str(),'\"')==NULL) sprintf(dir,"\"%s\"",arg.c_str()); else strcpy(dir,arg.c_str()); if (!DOS_MakeName(dir,fulldir,&drive)) throw 0; if( ( ldp=dynamic_cast<localDrive*>(Drives[drive])) == 0 ) throw 0; char newname[CROSS_LEN]; strcpy(newname, ldp->basedir); strcat(newname,fulldir); CROSS_FILENAME(newname); ldp->dirCache.ExpandName(newname); strcat(mountstring,"\""); strcat(mountstring, newname); strcat(mountstring,"\""); 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; } catch(...) { //dynamic cast failed =>so no localdrive WriteOut(MSG_Get("SHELL_CMD_SUBST_FAILURE")); return; } return; }
void DOS_Shell::SyntaxError(void) { WriteOut(MSG_Get("SHELL_SYNTAXERROR")); }
void CONFIG::Run(void) { static const char* const params[] = { "-r", "-wcp", "-wcd", "-wc", "-writeconf", "-l", "-rmconf", "-h", "-help", "-?", "-axclear", "-axadd", "-axtype", "-get", "-set", "-writelang", "-wl", "-securemode", "" }; enum prs { P_NOMATCH, P_NOPARAMS, // fixed return values for GetParameterFromList P_RESTART, P_WRITECONF_PORTABLE, P_WRITECONF_DEFAULT, P_WRITECONF, P_WRITECONF2, P_LISTCONF, P_KILLCONF, P_HELP, P_HELP2, P_HELP3, P_AUTOEXEC_CLEAR, P_AUTOEXEC_ADD, P_AUTOEXEC_TYPE, P_GETPROP, P_SETPROP, P_WRITELANG, P_WRITELANG2, P_SECURE } presult = P_NOMATCH; bool first = true; std::vector<std::string> pvars; // Loop through the passed parameters while(presult != P_NOPARAMS) { presult = (enum prs)cmd->GetParameterFromList(params, pvars); switch(presult) { case P_RESTART: if (securemode_check()) return; if (pvars.size() == 0) restart_program(control->startup_params); else { std::vector<std::string> restart_params; restart_params.push_back(control->cmdline->GetFileName()); for(size_t i = 0; i < pvars.size(); i++) { restart_params.push_back(pvars[i]); if (pvars[i].find(' ') != std::string::npos) { pvars[i] = "\""+pvars[i]+"\""; // add back spaces } } // the rest on the commandline, too cmd->FillVector(restart_params); restart_program(restart_params); } return; case P_LISTCONF: { Bitu size = control->configfiles.size(); std::string config_path; Cross::GetPlatformConfigDir(config_path); WriteOut(MSG_Get("PROGRAM_CONFIG_CONFDIR"), VERSION,config_path.c_str()); if (size==0) WriteOut(MSG_Get("PROGRAM_CONFIG_NOCONFIGFILE")); else { WriteOut(MSG_Get("PROGRAM_CONFIG_PRIMARY_CONF"),control->configfiles.front().c_str()); if (size > 1) { WriteOut(MSG_Get("PROGRAM_CONFIG_ADDITIONAL_CONF")); for(Bitu i = 1; i < size; i++) WriteOut("%s\n",control->configfiles[i].c_str()); } } if (control->startup_params.size() > 0) { std::string test; for(size_t k = 0; k < control->startup_params.size(); k++) test += control->startup_params[k] + " "; WriteOut(MSG_Get("PROGRAM_CONFIG_PRINT_STARTUP"), test.c_str()); } break; } case P_WRITECONF: case P_WRITECONF2: if (securemode_check()) return; if (pvars.size() > 1) return; else if (pvars.size() == 1) { // write config to specific file, except if it is an absolute path writeconf(pvars[0], !Cross::IsPathAbsolute(pvars[0])); } else { // -wc without parameter: write primary config file if (control->configfiles.size()) writeconf(control->configfiles[0], false); else WriteOut(MSG_Get("PROGRAM_CONFIG_NOCONFIGFILE")); } break; case P_WRITECONF_DEFAULT: { // write to /userdir/dosbox0.xx.conf if (securemode_check()) return; if (pvars.size() > 0) return; std::string confname; Cross::GetPlatformConfigName(confname); writeconf(confname, true); break; } case P_WRITECONF_PORTABLE: if (securemode_check()) return; if (pvars.size() > 1) return; else if (pvars.size() == 1) { // write config to startup directory writeconf(pvars[0], false); } else { // -wcp without parameter: write dosbox.conf to startup directory if (control->configfiles.size()) writeconf(std::string("dosbox.conf"), false); else WriteOut(MSG_Get("PROGRAM_CONFIG_NOCONFIGFILE")); } break; case P_NOPARAMS: if (!first) break; case P_NOMATCH: WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); return; case P_HELP: case P_HELP2: case P_HELP3: { switch(pvars.size()) { case 0: WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); return; case 1: { if (!strcasecmp("sections",pvars[0].c_str())) { // list the sections WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_SECTLIST")); Bitu i = 0; while(true) { Section* sec = control->GetSection(i++); if (!sec) break; WriteOut("%s\n",sec->GetName()); } return; } // if it's a section, leave it as one-param Section* sec = control->GetSection(pvars[0].c_str()); if (!sec) { // could be a property sec = control->GetSectionFromProperty(pvars[0].c_str()); if (!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); return; } pvars.insert(pvars.begin(),std::string(sec->GetName())); } break; } case 2: { // sanity check Section* sec = control->GetSection(pvars[0].c_str()); Section* sec2 = control->GetSectionFromProperty(pvars[1].c_str()); if (sec != sec2) { WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); } break; } default: WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); return; } // if we have one value in pvars, it's a section // two values are section + property Section* sec = control->GetSection(pvars[0].c_str()); if (sec==NULL) { WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); return; } Section_prop* psec = dynamic_cast <Section_prop*>(sec); if (psec==NULL) { // failed; maybe it's the autoexec section? Section_line* pline = dynamic_cast <Section_line*>(sec); if (pline==NULL) E_Exit("Section dynamic cast failed."); WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_LINEHLP"), pline->GetName(), // this is 'unclean' but the autoexec section has no help associated MSG_Get("AUTOEXEC_CONFIGFILE_HELP"), pline->data.c_str() ); return; } if (pvars.size()==1) { size_t i = 0; WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_SECTHLP"),pvars[0].c_str()); while(true) { // list the properties Property* p = psec->Get_prop(i++); if (p==NULL) break; WriteOut("%s\n", p->propname.c_str()); } } else { // find the property by it's name size_t i = 0; while (true) { Property *p = psec->Get_prop(i++); if (p==NULL) break; if (!strcasecmp(p->propname.c_str(),pvars[1].c_str())) { // found it; make the list of possible values std::string propvalues; std::vector<Value> pv = p->GetValues(); if (p->Get_type()==Value::V_BOOL) { // possible values for boolean are true, false propvalues += "true, false"; } else if (p->Get_type()==Value::V_INT) { // print min, max for integer values if used Prop_int* pint = dynamic_cast <Prop_int*>(p); if (pint==NULL) E_Exit("Int property dynamic cast failed."); if (pint->getMin() != pint->getMax()) { std::ostringstream oss; oss << pint->getMin(); oss << ".."; oss << pint->getMax(); propvalues += oss.str(); } } for(Bitu k = 0; k < pv.size(); k++) { if (pv[k].ToString() =="%u") propvalues += MSG_Get("PROGRAM_CONFIG_HLP_POSINT"); else propvalues += pv[k].ToString(); if ((k+1) < pv.size()) propvalues += ", "; } WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_PROPHLP"), p->propname.c_str(), sec->GetName(), p->Get_help(),propvalues.c_str(), p->Get_Default_Value().ToString().c_str(), p->GetValue().ToString().c_str()); // print 'changability' if (p->getChange()==Property::Changeable::OnlyAtStart) { WriteOut(MSG_Get("PROGRAM_CONFIG_HLP_NOCHANGE")); } return; } } break; } return; } case P_AUTOEXEC_CLEAR: { Section_line* sec = dynamic_cast <Section_line*> (control->GetSection(std::string("autoexec"))); sec->data.clear(); break; } case P_AUTOEXEC_ADD: { if (pvars.size() == 0) { WriteOut(MSG_Get("PROGRAM_CONFIG_MISSINGPARAM")); return; } Section_line* sec = dynamic_cast <Section_line*> (control->GetSection(std::string("autoexec"))); for(Bitu i = 0; i < pvars.size(); i++) sec->HandleInputline(pvars[i]); break; } case P_AUTOEXEC_TYPE: { Section_line* sec = dynamic_cast <Section_line*> (control->GetSection(std::string("autoexec"))); WriteOut("\n%s",sec->data.c_str()); break; } case P_GETPROP: { // "section property" // "property" // "section" // "section" "property" if (pvars.size()==0) { WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); return; } std::string::size_type spcpos = pvars[0].find_first_of(' '); // split on the ' ' if (spcpos != std::string::npos) { pvars.insert(++pvars.begin(),pvars[0].substr(spcpos+1)); pvars[0].erase(spcpos); } switch(pvars.size()) { case 1: { // property/section only // is it a section? Section* sec = control->GetSection(pvars[0].c_str()); if (sec) { // list properties in section Bitu i = 0; Section_prop* psec = dynamic_cast <Section_prop*>(sec); if (psec==NULL) { // autoexec section Section_line* pline = dynamic_cast <Section_line*>(sec); if (pline==NULL) E_Exit("Section dynamic cast failed."); WriteOut("%s",pline->data.c_str()); break; } while(true) { // list the properties Property* p = psec->Get_prop(i++); if (p==NULL) break; WriteOut("%s=%s\n", p->propname.c_str(), p->GetValue().ToString().c_str()); } } else { // no: maybe it's a property? sec = control->GetSectionFromProperty(pvars[0].c_str()); if (!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); return; } // it's a property name std::string val = sec->GetPropValue(pvars[0].c_str()); WriteOut("%s",val.c_str()); } break; } case 2: { // section + property Section* sec = control->GetSection(pvars[0].c_str()); if (!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR")); return; } std::string val = sec->GetPropValue(pvars[1].c_str()); if (val == NO_SUCH_PROPERTY) { WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"), pvars[1].c_str(),pvars[0].c_str()); return; } WriteOut("%s",val.c_str()); break; } default: WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); return; } return; } case P_SETPROP: { // Code for the configuration changes // Official format: config -set "section property=value" // Accepted: with or without -set, // "section property value" // "section property=value" // "property" "value" // "section" "property=value" // "section" "property=value" "value" "value" ... // "section" "property" "value" "value" ... // "section property" "value" "value" ... // "property" "value" "value" ... // "property=value" "value" "value" ... if (pvars.size()==0) { WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); return; } // add rest of command std::string rest; if (cmd->GetStringRemain(rest)) pvars.push_back(rest); // attempt to split off the first word std::string::size_type spcpos = pvars[0].find_first_of(' '); std::string::size_type equpos = pvars[0].find_first_of('='); if ((equpos != std::string::npos) && ((spcpos == std::string::npos) || (equpos < spcpos))) { // If we have a '=' possibly before a ' ' split on the = pvars.insert(++pvars.begin(),pvars[0].substr(equpos+1)); pvars[0].erase(equpos); // As we had a = the first thing must be a property now Section* sec=control->GetSectionFromProperty(pvars[0].c_str()); if (sec) pvars.insert(pvars.begin(),std::string(sec->GetName())); else { WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); return; } // order in the vector should be ok now } else { if ((spcpos != std::string::npos) && ((equpos == std::string::npos) || (spcpos < equpos))) { // ' ' before a possible '=', split on the ' ' pvars.insert(++pvars.begin(),pvars[0].substr(spcpos+1)); pvars[0].erase(spcpos); } // check if the first parameter is a section or property Section* sec = control->GetSection(pvars[0].c_str()); if (!sec) { // not a section: little duplicate from above Section* sec=control->GetSectionFromProperty(pvars[0].c_str()); if (sec) pvars.insert(pvars.begin(),std::string(sec->GetName())); else { WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR")); return; } } else { // first of pvars is most likely a section, but could still be gus // have a look at the second parameter if (pvars.size() < 2) { WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); return; } std::string::size_type spcpos2 = pvars[1].find_first_of(' '); std::string::size_type equpos2 = pvars[1].find_first_of('='); if ((equpos2 != std::string::npos) && ((spcpos2 == std::string::npos) || (equpos2 < spcpos2))) { // split on the = pvars.insert(pvars.begin()+2,pvars[1].substr(equpos2+1)); pvars[1].erase(equpos2); } else if ((spcpos2 != std::string::npos) && ((equpos2 == std::string::npos) || (spcpos2 < equpos2))) { // split on the ' ' pvars.insert(pvars.begin()+2,pvars[1].substr(spcpos2+1)); pvars[1].erase(spcpos2); } // is this a property? Section* sec2 = control->GetSectionFromProperty(pvars[1].c_str()); if (!sec2) { // not a property, Section* sec3 = control->GetSectionFromProperty(pvars[0].c_str()); if (sec3) { // section and property name are identical pvars.insert(pvars.begin(),pvars[0]); } // else has been checked above already } } } if(pvars.size() < 3) { WriteOut(MSG_Get("PROGRAM_CONFIG_SET_SYNTAX")); return; } // check if the property actually exists in the section Section* sec2 = control->GetSectionFromProperty(pvars[1].c_str()); if (!sec2) { WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"), pvars[1].c_str(),pvars[0].c_str()); return; } // Input has been parsed (pvar[0]=section, [1]=property, [2]=value) // now execute Section* tsec = control->GetSection(pvars[0]); std::string value; value += pvars[2]; for(Bitu i = 3; i < pvars.size(); i++) value += (std::string(" ") + pvars[i]); std::string inputline = pvars[1] + "=" + value; tsec->ExecuteDestroy(false); bool change_success = tsec->HandleInputline(inputline.c_str()); if (!change_success) WriteOut(MSG_Get("PROGRAM_CONFIG_VALUE_ERROR"), value.c_str(),pvars[1].c_str()); tsec->ExecuteInit(false); return; } case P_WRITELANG: case P_WRITELANG2: // In secure mode don't allow a new languagefile to be created // Who knows which kind of file we would overwrite. if (securemode_check()) return; if (pvars.size() < 1) { WriteOut(MSG_Get("PROGRAM_CONFIG_MISSINGPARAM")); return; } if (!MSG_Write(pvars[0].c_str())) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),pvars[0].c_str()); return; } break; case P_SECURE: // Code for switching to secure mode control->SwitchToSecureMode(); WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON")); return; default: E_Exit("bug"); break; } first = false; } return; }
void DOS_Shell::Run(void) { char input_line[CMD_MAXLINE] = {0}; std::string line; if (cmd->FindStringRemain("/C",line)) { strcpy(input_line,line.c_str()); char* sep = strpbrk(input_line,"\r\n"); //GTA installer if (sep) *sep = 0; DOS_Shell temp; temp.echo = echo; temp.ParseLine(input_line); //for *.exe *.com |*.bat creates the bf needed by runinternal; temp.RunInternal(); // exits when no bf is found. return; } /* Start a normal shell and check for a first command init */ WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION); #if C_DEBUG WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); WriteOut(MSG_Get("SHELL_STARTUP_END")); #ifdef IPHONEOS if (automount_path[0]) { char *p = (char*)automount_path; char *endp = p; char disk = 'c'; LOG_MSG("DOS_Shell::Run Auto Mount"); while (endp) { for (p = endp; *endp && *endp != ';'; endp++) ; if (*endp == ';') { *endp = 0; endp++; } else { endp=0; } if (strlen(p) <= 0) break; sprintf(input_line, "mount %c \"%s\"",disk, p); ParseLine(input_line); disk++; } if (disk > 'c') { sprintf(input_line, "c:"); ParseLine(input_line); } } #endif if (cmd->FindString("/INIT",line,true)) { strcpy(input_line,line.c_str()); line.erase(); ParseLine(input_line); } do { if (bf){ if(bf->ReadLine(input_line)) { if (echo) { if (input_line[0]!='@') { ShowPrompt(); WriteOut_NoParsing(input_line); WriteOut_NoParsing("\n"); }; }; ParseLine(input_line); if (echo) WriteOut("\n"); } #ifdef IPHONEOS } else if (automount_path[0]) { automount_path[0] = 0; if (echo && !bf) WriteOut_NoParsing("\n"); sprintf(input_line, "cls"); ParseLine(input_line); #endif } else { if (echo) ShowPrompt(); #ifdef IPHONEOS dospad_command_line_ready=1; #endif InputCommand(input_line); #ifdef IPHONEOS dospad_add_history(input_line); dospad_command_line_ready=0; if (dospad_should_launch_game) { // Make sure we can access the new installed files Bit8u drive = DOS_GetDefaultDrive(); if (Drives[drive]) { Drives[drive]->EmptyCache(); } FILE *fp=fopen(dospad_launch_config, "r"); if (fp != NULL) { char buf[256]; int sectionLength = strlen(dospad_launch_section); while (fgets(buf, 256, fp)) { if (strncmp(buf, dospad_launch_section, sectionLength) == 0) { while (fgets(buf, 256, fp)) { if (buf[0] == '[') break; if (buf[0] == '#') continue; ParseLine(buf); } } } fclose(fp); } dospad_should_launch_game = 0; sprintf(input_line,"cls"); dospad_launch_done(); } #endif ParseLine(input_line); if (echo && !bf) WriteOut_NoParsing("\n"); } } while (!exit); }
void DOS_Shell::CMD_COPY(char * args) { HELP("COPY"); static char defaulttarget[] = "."; StripSpaces(args); /* Command uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); DOS_DTA dta(dos.dta()); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII], lname[LFN_NAMELENGTH+1]; std::vector<copysource> sources; // ignore /b and /t switches: always copy binary while(ScanCMDBool(args,"B")) ; while(ScanCMDBool(args,"T")) ; //Shouldn't this be A ? while(ScanCMDBool(args,"A")) ; ScanCMDBool(args,"Y"); ScanCMDBool(args,"-Y"); ScanCMDBool(args,"V"); char * rem=ScanCMDRemain(args); if (rem) { WriteOut(MSG_Get("SHELL_ILLEGAL_SWITCH"),rem); dos.dta(save_dta); return; } // Gather all sources (extension to copy more then 1 file specified at command line) // Concatenating files go as follows: All parts except for the last bear the concat flag. // This construction allows them to be counted (only the non concat set) char q[]="\""; char* source_p = NULL; char source_x[DOS_PATHLENGTH+CROSS_LEN]; while ( (source_p = StripArg(args)) && *source_p ) { do { char* plus = strchr(source_p,'+'); // If StripWord() previously cut at a space before a plus then // set concatenate flag on last source and remove leading plus. if (plus == source_p && sources.size()) { sources[sources.size()-1].concat = true; // If spaces also followed plus then item is only a plus. if (strlen(++source_p)==0) break; plus = strchr(source_p,'+'); } if (plus) *plus++ = 0; safe_strncpy(source_x,source_p,CROSS_LEN); bool has_drive_spec = false; size_t source_x_len = strlen(source_x); if (source_x_len>0) { if (source_x[source_x_len-1]==':') has_drive_spec = true; } if (!has_drive_spec && !strpbrk(source_p,"*?") ) { //doubt that fu*\*.* is valid char spath[DOS_PATHLENGTH]; if (DOS_GetSFNPath(source_p,spath,false) && DOS_FindFirst(spath,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,lname,size,date,time,attr); if (attr & DOS_ATTR_DIRECTORY) strcat(source_x,"\\*.*"); } } sources.push_back(copysource(source_x,(plus)?true:false)); source_p = plus; } while(source_p && *source_p); } // At least one source has to be there if (!sources.size() || !sources[0].filename.size()) { WriteOut(MSG_Get("SHELL_MISSING_PARAMETER")); dos.dta(save_dta); return; }; copysource target; // If more then one object exists and last target is not part of a // concat sequence then make it the target. if(sources.size()>1 && !sources[sources.size()-2].concat){ target = sources.back(); sources.pop_back(); } //If no target => default target with concat flag true to detect a+b+c if(target.filename.size() == 0) target = copysource(defaulttarget,true); copysource oldsource; copysource source; Bit32u count = 0; while(sources.size()) { /* Get next source item and keep track of old source for concat start end */ oldsource = source; source = sources[0]; sources.erase(sources.begin()); //Skip first file if doing a+b+c. Set target to first file if(!oldsource.concat && source.concat && target.concat) { target = source; continue; } /* Make a full path in the args */ char pathSourcePre[DOS_PATHLENGTH], pathSource[DOS_PATHLENGTH+2]; char pathTarget[DOS_PATHLENGTH]; if (!DOS_Canonicalize(const_cast<char*>(source.filename.c_str()),pathSourcePre)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); dos.dta(save_dta); return; } strcpy(pathSource,pathSourcePre); if (uselfn) sprintf(pathSource,"\"%s\"",pathSourcePre); // cut search pattern char* pos = strrchr(pathSource,'\\'); if (pos) *(pos+1) = 0; if (!DOS_Canonicalize(const_cast<char*>(target.filename.c_str()),pathTarget)) { WriteOut(MSG_Get("SHELL_ILLEGAL_PATH")); dos.dta(save_dta); return; } char* temp = strstr(pathTarget,"*.*"); if(temp) *temp = 0;//strip off *.* from target // add '\\' if target is a directory bool target_is_file = true; if (pathTarget[strlen(pathTarget)-1]!='\\') { if (DOS_FindFirst(pathTarget,0xffff & ~DOS_ATTR_VOLUME)) { dta.GetResult(name,lname,size,date,time,attr); if (attr & DOS_ATTR_DIRECTORY) { strcat(pathTarget,"\\"); target_is_file = false; } } } else target_is_file = false; //Find first sourcefile char sPath[DOS_PATHLENGTH]; bool ret = DOS_GetSFNPath(source.filename.c_str(),sPath,false) && DOS_FindFirst(const_cast<char*>(sPath),0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),const_cast<char*>(source.filename.c_str())); dos.dta(save_dta); return; } Bit16u sourceHandle,targetHandle; char nameTarget[DOS_PATHLENGTH]; char nameSource[DOS_PATHLENGTH]; bool second_file_of_current_source = false; while (ret) { dta.GetResult(name,lname,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 or open it if in concat mode strcpy(nameTarget,q); strcat(nameTarget,pathTarget); if (nameTarget[strlen(nameTarget)-1]=='\\') strcat(nameTarget,uselfn?lname:name); strcat(nameTarget,q); //Special variable to ensure that copy * a_file, where a_file is not a directory concats. bool special = second_file_of_current_source && target_is_file; second_file_of_current_source = true; if (special) oldsource.concat = true; //Don't create a new file when in concat mode if (oldsource.concat || DOS_CreateFile(nameTarget,0,&targetHandle)) { Bit32u dummy=0; //In concat mode. Open the target and seek to the eof if (!oldsource.concat || (DOS_OpenFile(nameTarget,OPEN_READWRITE,&targetHandle) && DOS_SeekFile(targetHandle,&dummy,DOS_SEEK_END))) { // Copy static Bit8u buffer[0x8000]; // static, otherwise stack overflow possible. 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); if (strcmp(name,lname)&&uselfn) WriteOut(" %s [%s]\n",lname,name); else WriteOut(" %s\n",uselfn?lname:name); if(!source.concat && !special) count++; //Only count concat files once } else { DOS_CloseFile(sourceHandle); WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast<char*>(target.filename.c_str())); } } else { DOS_CloseFile(sourceHandle); WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast<char*>(target.filename.c_str())); } } else WriteOut(MSG_Get("SHELL_CMD_COPY_FAILURE"),const_cast<char*>(source.filename.c_str())); }; //On to the next file if the previous one wasn't a device if ((attr&DOS_ATTR_DEVICE) == 0) ret = DOS_FindNext(); else ret = false; }; } WriteOut(MSG_Get("SHELL_CMD_COPY_SUCCESS"),count); dos.dta(save_dta); }
void CONFIG::Run(void) { FILE * f; if (cmd->FindString("-writeconf",temp_line,true) || cmd->FindString("-wc",temp_line,true)) { /* In secure mode don't allow a new configfile to be created */ if(control->SecureMode()) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); return; } f=fopen(temp_line.c_str(),"wb+"); if (!f) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); return; } fclose(f); control->PrintConfig(temp_line.c_str()); return; } if (cmd->FindString("-writelang",temp_line,true) ||cmd->FindString("-wl",temp_line,true)) { /* In secure mode don't allow a new languagefile to be created * Who knows which kind of file we would overwriting. */ if(control->SecureMode()) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_DISALLOW")); return; } f=fopen(temp_line.c_str(),"wb+"); if (!f) { WriteOut(MSG_Get("PROGRAM_CONFIG_FILE_ERROR"),temp_line.c_str()); return; } fclose(f); MSG_Write(temp_line.c_str()); return; } /* Code for switching to secure mode */ if(cmd->FindExist("-securemode",true)) { control->SwitchToSecureMode(); WriteOut(MSG_Get("PROGRAM_CONFIG_SECURE_ON")); return; } /* Code for getting the current configuration. * * Official format: config -get "section property" * * As a bonus it will set %CONFIG% to this value as well */ if(cmd->FindString("-get",temp_line,true)) { std::string temp2 = ""; cmd->GetStringRemain(temp2);//So -get n1 n2= can be used without quotes if(temp2 != "") temp_line = temp_line + " " + temp2; std::string::size_type space = temp_line.find(" "); if(space == std::string::npos) { WriteOut(MSG_Get("PROGRAM_CONFIG_GET_SYNTAX")); return; } //Copy the found property to a new string and erase from templine (mind the space) std::string prop = temp_line.substr(space+1); temp_line.erase(space); Section* sec = control->GetSection(temp_line.c_str()); if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),temp_line.c_str()); return; } std::string val = sec->GetPropValue(prop.c_str()); if(val == NO_SUCH_PROPERTY) { WriteOut(MSG_Get("PROGRAM_CONFIG_NO_PROPERTY"),prop.c_str(),temp_line.c_str()); return; } WriteOut("%s",val.c_str()); first_shell->SetEnv("CONFIG",val.c_str()); return; } /* Code for the configuration changes * * Official format: config -set "section property=value" * * Accepted: without quotes and/or without -set and/or without section * * and/or the "=" replaced by a " " */ if (cmd->FindString("-set",temp_line,true)) { //get all arguments std::string temp2 = ""; cmd->GetStringRemain(temp2);//So -set n1 n2=n3 can be used without quotes if(temp2!="") temp_line = temp_line + " " + temp2; } else if(!cmd->GetStringRemain(temp_line)) {//no set WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); //and no arguments specified return; }; //Wanted input: n1 n2=n3 char copy[1024]; strcpy(copy,temp_line.c_str()); //seperate section from property const char* temp = strchr(copy,' '); if((temp && *temp) || (temp=strchr(copy,'=')) ) copy[temp++ - copy]= 0; else { WriteOut(MSG_Get("PROGRAM_CONFIG_USAGE")); return; } //if n1 n2 n3 then replace last space with = const char* sign = strchr(temp,'='); if(!sign) { sign = strchr(temp,' '); if(sign) { copy[sign - copy] = '='; } else { //2 items specified (no space nor = between n2 and n3 //assume that they posted: property value //Try to determine the section. Section* sec=control->GetSectionFromProperty(copy); if(!sec){ if(control->GetSectionFromProperty(temp)) return; //Weird situation:ignore WriteOut(MSG_Get("PROGRAM_CONFIG_PROPERTY_ERROR"),copy); return; } //Hack to allow config ems true char buffer[1024];strcpy(buffer,copy);strcat(buffer,"=");strcat(buffer,temp); sign = strchr(buffer,' '); if(sign) buffer[sign - buffer] = '='; strcpy(copy,sec->GetName()); temp = buffer; } } /* Input processed. Now the real job starts * copy contains the likely "sectionname" * temp contains "property=value" * the section is destroyed and a new input line is given to * the configuration parser. Then the section is restarted. */ char* inputline = const_cast<char*>(temp); Section* sec = 0; sec = control->GetSection(copy); if(!sec) { WriteOut(MSG_Get("PROGRAM_CONFIG_SECTION_ERROR"),copy);return;} sec->ExecuteDestroy(false); sec->HandleInputline(inputline); sec->ExecuteInit(false); return; }
void DOS_Shell::CMD_IF(char * args) { HELP("IF"); StripSpaces(args,'='); bool has_not=false; while (strncasecmp(args,"NOT",3) == 0) { if (!isspace(*reinterpret_cast<unsigned char*>(&args[3])) && (args[3] != '=')) break; args += 3; //skip text //skip more spaces StripSpaces(args,'='); has_not = !has_not; } if(strncasecmp(args,"ERRORLEVEL",10) == 0) { args += 10; //skip text //Strip spaces and == StripSpaces(args,'='); char* word = StripWord(args); 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 */ if ((dos.return_code>=n) ==(!has_not)) DoCommand(args); return; } if(strncasecmp(args,"EXIST ",6) == 0) { args += 6; //Skip text StripSpaces(args); char* word = StripArg(args); if (!*word) { WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME")); return; } { /* DOS_FindFirst uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); bool ret=DOS_FindFirst(word,0xffff & ~DOS_ATTR_VOLUME); dos.dta(save_dta); if (ret==(!has_not)) DoCommand(args); } return; } /* Normal if string compare */ char* word1 = args; // first word is until space or = while (*args && !isspace(*reinterpret_cast<unsigned char*>(args)) && (*args != '=')) args++; char* end_word1 = args; // scan for = while (*args && (*args != '=')) args++; // check for == if ((*args==0) || (args[1] != '=')) { SyntaxError(); return; } args += 2; StripSpaces(args,'='); char* word2 = args; // second word is until space or = while (*args && !isspace(*reinterpret_cast<unsigned char*>(args)) && (*args != '=')) args++; if (*args) { *end_word1 = 0; // mark end of first word *args++ = 0; // mark end of second word StripSpaces(args,'='); if ((strcmp(word1,word2)==0)==(!has_not)) DoCommand(args); } }