From def259b02edd6a9e335fc94ea787da67442abc87 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 4 Jun 2007 18:09:27 +0000 Subject: [PATCH] Add support for ~username to mount and imgmount. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2873 --- src/dos/dos_programs.cpp | 88 +++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 29 deletions(-) diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 28c90cca..a1176c0e 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -16,8 +16,9 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_programs.cpp,v 1.72 2007-05-27 16:11:35 c2woody Exp $ */ +/* $Id: dos_programs.cpp,v 1.73 2007-06-04 18:09:27 qbix79 Exp $ */ +#include "dosbox.h" #include #include #include @@ -34,6 +35,12 @@ #include "dos_inc.h" #include "bios.h" +#if defined HAVE_SYS_TYPES_H && defined HAVE_PWD_H +#include +#include +#endif + + #if defined(OS2) #define INCL DOSFILEMGR #define INCL_DOSERRORS @@ -46,6 +53,24 @@ Bitu DEBUG_EnableDebugger(void); void MSCDEX_SetCDInterface(int intNr, int forceCD); +//Helper function for mount and imgmount to correctly find the path +static void 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 + } +} + class MOUNT : public Program { public: void Run(void) @@ -184,11 +209,9 @@ public: #else if (stat(temp_line.c_str(),&test)) { failed = true; - if(temp_line.size() && temp_line[0] == '~') { - char * home = getenv("HOME"); - if(home) temp_line.replace(0,1,std::string(home)); - if(!stat(temp_line.c_str(),&test)) failed = false; - } + ResolveHomedir(temp_line); + //Try again after resolving ~ + if(!stat(temp_line.c_str(),&test)) failed = false; } if(failed) { #endif @@ -954,29 +977,36 @@ public: struct stat test; if (stat(temp_line.c_str(),&test)) { - // convert dosbox filename to system filename - char fullname[CROSS_LEN]; - char tmp[CROSS_LEN]; - safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); - - Bit8u dummy; - if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE")); - return; - } - - localDrive *ldp = (localDrive*)Drives[dummy]; - ldp->GetSystemFilename(tmp, fullname); - temp_line = tmp; - - if (stat(temp_line.c_str(),&test)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); - return; - } - - if ((test.st_mode & S_IFDIR)) { - WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); - return; + //See if it works if the ~ are written out + std::string homedir(temp_line); + ResolveHomedir(homedir); + if(!stat(homedir.c_str(),&test)) { + temp_line = homedir; + } else { + // convert dosbox filename to system filename + char fullname[CROSS_LEN]; + char tmp[CROSS_LEN]; + safe_strncpy(tmp, temp_line.c_str(), CROSS_LEN); + + Bit8u dummy; + if (!DOS_MakeName(tmp, fullname, &dummy) || strncmp(Drives[dummy]->GetInfo(),"local directory",15)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_NON_LOCAL_DRIVE")); + return; + } + + localDrive *ldp = (localDrive*)Drives[dummy]; + ldp->GetSystemFilename(tmp, fullname); + temp_line = tmp; + + if (stat(temp_line.c_str(),&test)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_FILE_NOT_FOUND")); + return; + } + + if ((test.st_mode & S_IFDIR)) { + WriteOut(MSG_Get("PROGRAM_IMGMOUNT_MOUNT")); + return; + } } } paths.push_back(temp_line);