2010-11-05 05:55:33 +01:00
|
|
|
/*
|
2011-06-22 06:18:55 +02:00
|
|
|
* Copyright (C) 2002-2011 The DOSBox Team
|
2010-11-05 05:55:33 +01: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
|
|
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include "dosbox.h"
|
|
|
|
#include "cross.h"
|
|
|
|
#include "support.h"
|
|
|
|
#include <string>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#ifdef HW_RVL
|
|
|
|
#include "wiihardware.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#ifndef _WIN32_IE
|
|
|
|
#define _WIN32_IE 0x0400
|
|
|
|
#endif
|
|
|
|
#include <shlobj.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
static void W32_ConfDir(std::string& in,bool create) {
|
|
|
|
int c = create?1:0;
|
|
|
|
char result[MAX_PATH] = { 0 };
|
|
|
|
BOOL r = SHGetSpecialFolderPath(NULL,result,CSIDL_LOCAL_APPDATA,c);
|
|
|
|
if(!r || result[0] == 0) r = SHGetSpecialFolderPath(NULL,result,CSIDL_APPDATA,c);
|
|
|
|
if(!r || result[0] == 0) {
|
|
|
|
char const * windir = getenv("windir");
|
|
|
|
if(!windir) windir = "c:\\windows";
|
|
|
|
safe_strncpy(result,windir,MAX_PATH);
|
|
|
|
char const* appdata = "\\Application Data";
|
|
|
|
size_t len = strlen(result);
|
|
|
|
if(len + strlen(appdata) < MAX_PATH) strcat(result,appdata);
|
|
|
|
if(create) mkdir(result);
|
|
|
|
}
|
|
|
|
in = result;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void Cross::GetPlatformConfigDir(std::string& in) {
|
|
|
|
#ifdef WIN32
|
|
|
|
W32_ConfDir(in,false);
|
|
|
|
in += "\\DOSBox";
|
|
|
|
#elif defined(MACOSX)
|
|
|
|
in = "~/Library/Preferences";
|
|
|
|
ResolveHomedir(in);
|
|
|
|
#elif defined(HW_RVL)
|
|
|
|
in = "sd:/DOSBox";
|
|
|
|
#else
|
|
|
|
in = "~/.dosbox";
|
|
|
|
ResolveHomedir(in);
|
|
|
|
#endif
|
|
|
|
in += CROSS_FILESPLIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Cross::GetPlatformConfigName(std::string& in) {
|
|
|
|
#ifdef WIN32
|
|
|
|
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
|
|
|
|
#elif defined(MACOSX)
|
|
|
|
#define DEFAULT_CONFIG_FILE "DOSBox " VERSION " Preferences"
|
|
|
|
#elif defined(HW_RVL)
|
|
|
|
#define DEFAULT_CONFIG_FILE "dosbox.conf"
|
|
|
|
#else /*linux freebsd*/
|
|
|
|
#define DEFAULT_CONFIG_FILE "dosbox-" VERSION ".conf"
|
|
|
|
#endif
|
|
|
|
in = DEFAULT_CONFIG_FILE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Cross::CreatePlatformConfigDir(std::string& in) {
|
|
|
|
#ifdef WIN32
|
|
|
|
W32_ConfDir(in,true);
|
|
|
|
in += "\\DOSBox";
|
|
|
|
mkdir(in.c_str());
|
|
|
|
#elif defined(MACOSX)
|
|
|
|
in = "~/Library/Preferences/";
|
|
|
|
ResolveHomedir(in);
|
|
|
|
//Don't create it. Assume it exists
|
|
|
|
#elif defined(HW_RVL)
|
|
|
|
in = "sd:/DOSBox";
|
|
|
|
CreateDir(in);
|
|
|
|
#else
|
|
|
|
in = "~/.dosbox";
|
|
|
|
ResolveHomedir(in);
|
|
|
|
mkdir(in.c_str(),0700);
|
|
|
|
#endif
|
|
|
|
in += CROSS_FILESPLIT;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Cross::ResolveHomedir(std::string & temp_line) {
|
|
|
|
if(!temp_line.size() || temp_line[0] != '~') return; //No ~
|
|
|
|
|
|
|
|
if(temp_line.size() == 1 || temp_line[1] == CROSS_FILESPLIT) { //The ~ and ~/ variant
|
|
|
|
char * home = getenv("HOME");
|
|
|
|
if(home) temp_line.replace(0,1,std::string(home));
|
|
|
|
#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H
|
|
|
|
} else { // The ~username variant
|
|
|
|
std::string::size_type namelen = temp_line.find(CROSS_FILESPLIT);
|
|
|
|
if(namelen == std::string::npos) namelen = temp_line.size();
|
|
|
|
std::string username = temp_line.substr(1,namelen - 1);
|
|
|
|
struct passwd* pass = getpwnam(username.c_str());
|
|
|
|
if(pass) temp_line.replace(0,namelen,pass->pw_dir); //namelen -1 +1(for the ~)
|
|
|
|
#endif // USERNAME lookup code
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Cross::CreateDir(std::string const& in) {
|
|
|
|
#ifdef WIN32
|
|
|
|
mkdir(in.c_str());
|
|
|
|
#else
|
|
|
|
mkdir(in.c_str(),0700);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Cross::IsPathAbsolute(std::string const& in) {
|
|
|
|
// Absolute paths
|
|
|
|
#if defined (WIN32) || defined(OS2)
|
|
|
|
// drive letter
|
|
|
|
if (in.size() > 2 && in[1] == ':' ) return true;
|
|
|
|
// UNC path
|
|
|
|
else if (in.size() > 2 && in[0]=='\\' && in[1]=='\\') return true;
|
|
|
|
#elif defined (HW_RVL)
|
|
|
|
if (in.size() > 3 &&
|
|
|
|
in[0] == 's' &&
|
|
|
|
in[1] == 'd' &&
|
|
|
|
in[2] == ':')
|
|
|
|
return true;
|
|
|
|
else if (in.size() > 5 &&
|
|
|
|
in[0] == 'u' &&
|
|
|
|
in[1] == 's' &&
|
|
|
|
in[2] == 'b' &&
|
|
|
|
in[4] == ':' )
|
|
|
|
return true;
|
|
|
|
#else
|
|
|
|
if (in.size() > 1 && in[0] == '/' ) return true;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined (WIN32)
|
|
|
|
|
|
|
|
dir_information* open_directory(const char* dirname) {
|
|
|
|
if (dirname == NULL) return NULL;
|
|
|
|
|
|
|
|
size_t len = strlen(dirname);
|
|
|
|
if (len == 0) return NULL;
|
|
|
|
|
|
|
|
static dir_information dir;
|
|
|
|
|
|
|
|
safe_strncpy(dir.base_path,dirname,MAX_PATH);
|
|
|
|
|
|
|
|
if (dirname[len-1] == '\\') strcat(dir.base_path,"*.*");
|
|
|
|
else strcat(dir.base_path,"\\*.*");
|
|
|
|
|
|
|
|
dir.handle = INVALID_HANDLE_VALUE;
|
|
|
|
|
|
|
|
return (access(dirname,0) ? NULL : &dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
|
|
dirp->handle = FindFirstFile(dirp->base_path, &dirp->search_data);
|
|
|
|
if (INVALID_HANDLE_VALUE == dirp->handle) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
|
|
|
|
|
|
|
|
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
|
|
|
|
else is_directory = false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
|
|
int result = FindNextFile(dirp->handle, &dirp->search_data);
|
|
|
|
if (result==0) return false;
|
|
|
|
|
|
|
|
safe_strncpy(entry_name,dirp->search_data.cFileName,(MAX_PATH<CROSS_LEN)?MAX_PATH:CROSS_LEN);
|
|
|
|
|
|
|
|
if (dirp->search_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) is_directory = true;
|
|
|
|
else is_directory = false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void close_directory(dir_information* dirp) {
|
|
|
|
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
|
|
|
FindClose(dirp->handle);
|
|
|
|
dirp->handle = INVALID_HANDLE_VALUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
dir_information* open_directory(const char* dirname) {
|
|
|
|
static dir_information dir;
|
|
|
|
dir.dir=opendir(dirname);
|
|
|
|
safe_strncpy(dir.base_path,dirname,CROSS_LEN);
|
|
|
|
return dir.dir?&dir:NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
|
|
struct dirent* dentry = readdir(dirp->dir);
|
|
|
|
if (dentry==NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
|
|
|
|
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
|
|
|
|
|
|
|
#ifdef DIRENT_HAS_D_TYPE
|
|
|
|
if(dentry->d_type == DT_DIR) {
|
|
|
|
is_directory = true;
|
|
|
|
return true;
|
|
|
|
} else if(dentry->d_type == DT_REG) {
|
|
|
|
is_directory = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// probably use d_type here instead of a full stat()
|
|
|
|
static char buffer[2*CROSS_LEN] = { 0 };
|
|
|
|
buffer[0] = 0;
|
|
|
|
strcpy(buffer,dirp->base_path);
|
|
|
|
strcat(buffer,entry_name);
|
|
|
|
struct stat status;
|
|
|
|
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
|
|
|
|
else is_directory = false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory) {
|
|
|
|
struct dirent* dentry = readdir(dirp->dir);
|
|
|
|
if (dentry==NULL) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// safe_strncpy(entry_name,dentry->d_name,(FILENAME_MAX<MAX_PATH)?FILENAME_MAX:MAX_PATH); // [include stdio.h], maybe pathconf()
|
|
|
|
safe_strncpy(entry_name,dentry->d_name,CROSS_LEN);
|
|
|
|
|
|
|
|
#ifdef DIRENT_HAS_D_TYPE
|
|
|
|
if(dentry->d_type == DT_DIR) {
|
|
|
|
is_directory = true;
|
|
|
|
return true;
|
|
|
|
} else if(dentry->d_type == DT_REG) {
|
|
|
|
is_directory = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// probably use d_type here instead of a full stat()
|
|
|
|
static char buffer[2*CROSS_LEN] = { 0 };
|
|
|
|
buffer[0] = 0;
|
|
|
|
strcpy(buffer,dirp->base_path);
|
|
|
|
strcat(buffer,entry_name);
|
|
|
|
struct stat status;
|
|
|
|
|
|
|
|
if (stat(buffer,&status)==0) is_directory = (S_ISDIR(status.st_mode)>0);
|
|
|
|
else is_directory = false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void close_directory(dir_information* dirp) {
|
|
|
|
closedir(dirp->dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|