1 // $Id: pathnmex.cpp 836 2006-04-18 16:06:15Z gerry $
2 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
3 ================================XARAHEADERSTART===========================
5 Xara LX, a vector drawing and manipulation program.
6 Copyright (C) 1993-2006 Xara Group Ltd.
7 Copyright on certain contributions may be held in joint with their
8 respective authors. See AUTHORS file for details.
10 LICENSE TO USE AND MODIFY SOFTWARE
11 ----------------------------------
13 This file is part of Xara LX.
15 Xara LX is free software; you can redistribute it and/or modify it
16 under the terms of the GNU General Public License version 2 as published
17 by the Free Software Foundation.
19 Xara LX and its component source files are distributed in the hope
20 that it will be useful, but WITHOUT ANY WARRANTY; without even the
21 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22 See the GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License along
25 with Xara LX (see the file GPL in the root directory of the
26 distribution); if not, write to the Free Software Foundation, Inc., 51
27 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
33 Conditional upon your continuing compliance with the GNU General Public
34 License described above, Xara Group Ltd grants to you certain additional
37 The additional rights are to use, modify, and distribute the software
38 together with the wxWidgets library, the wxXtra library, and the "CDraw"
39 library and any other such library that any version of Xara LX relased
40 by Xara Group Ltd requires in order to compile and execute, including
41 the static linking of that library to XaraLX. In the case of the
42 "CDraw" library, you may satisfy obligation under the GNU General Public
43 License to provide source code by providing a binary copy of the library
44 concerned and a copy of the license accompanying it.
46 Nothing in this section restricts any of the rights you have under
47 the GNU General Public License.
53 This license applies to this program (XaraLX) and its constituent source
54 files only, and does not necessarily apply to other Xara products which may
55 in part share the same code base, and are subject to their own licensing
58 This license does not apply to files in the wxXtra directory, which
59 are built into a separate library, and are subject to the wxWindows
60 license contained within that directory in the file "WXXTRA-LICENSE".
62 This license does not apply to the binary libraries (if any) within
63 the "libs" directory, which are subject to a separate license contained
64 within that directory in the file "LIBS-LICENSE".
67 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
68 ----------------------------------------------
70 Subject to the terms of the GNU Public License (see above), you are
71 free to do whatever you like with your modifications. However, you may
72 (at your option) wish contribute them to Xara's source tree. You can
73 find details of how to do this at:
74 http://www.xaraxtreme.org/developers/
76 Prior to contributing your modifications, you will need to complete our
77 contributor agreement. This can be found at:
78 http://www.xaraxtreme.org/developers/contribute/
80 Please note that Xara will not accept modifications which modify any of
81 the text between the start and end of this header (marked
82 XARAHEADERSTART and XARAHEADEREND).
88 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
89 designs are registered or unregistered trademarks, design-marks, and/or
90 service marks of Xara Group Ltd. All rights in these marks are reserved.
93 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
96 =================================XARAHEADEREND============================
101 #include "pathnmex.h"
102 //#include "webster.h"
104 #include <sys/types.h>
105 #include <sys/stat.h>
110 #if defined(__WXMSW__)
115 const TCHAR chPathSep
= _T('\\');
117 const TCHAR chPathSep
= _T('/');
120 /********************************************************************************************
122 > BOOL PathNameEx::CreateLocation()
124 Author: Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
127 Return: TRUE if successful, FALSE otherwise
128 Purpose: Creates the full directory path (as returned by GetLocation())
129 on the physical medium. This is useful when creating new
130 directory structures.
133 ********************************************************************************************/
135 BOOL
PathNameEx::CreateLocation()
137 PORTNOTETRACE("other","PathNameEx::CreateLocation - do nothing");
138 #ifndef EXCLUDE_FROM_XARALX
142 // We'll walk the location string from left to right - if we come across non-existent directories,
144 String_256 strLocation
= GetLocation(FALSE
);
145 String_256 strDirPath
= drivename
;
146 INT32 nPos
= drivename
.Length(); // start after the drivename
147 while( nPos
< strLocation
.Length() )
149 while( ( strLocation
[nPos
] != chPathSep
) && ( nPos
< strLocation
.Length() ) )
151 strDirPath
+= strLocation
[nPos
];
154 // strDirPath has been added a directory, we check if it exists
156 if (_access((TCHAR
*) strDirPath
, 0) == -1) // not found, try to create the directory
158 if (_mkdir((TCHAR
*) strDirPath
))
166 camStrcpy(szError
, "access denied (EACCES)");
169 camStrcpy(szError
, "path not found (ENOENT)");
172 wsprintf(szError
, "errno = %d", errno
);
174 wsprintf(szMsg
, "Create directory %s failed, %s", strDirPath
, szError
);
180 strDirPath
+= chPathSep
; // add a backslash in case there are further subdirectories
181 nPos
++; // move to the next position
189 /********************************************************************************************
191 > BOOL PathNameEx::RemoveRecursively()
193 Author: Adrian_Stoicar (Xara Group Ltd) <camelotdev@xara.com>
196 Return: TRUE if the path is completely deleted, FALSE otherwise (access denied
197 or invalid parameters). In case some files cannot be removed, the function will
198 do its best to remove the all accessible ones without falling over, unlike the
199 NT system call RMDIR which stops at the first file it can't delete.
200 Purpose: Removes a file or a whole directory tree from the the physical medium (in
201 which case, the object should be pointing to the root directory of the tree
205 ********************************************************************************************/
208 BOOL
PathNameEx::RemoveRecursively(const String_256
& rPath
)
210 PORTNOTETRACE("other","PathNameEx::RemoveRecursively - do nothing");
211 #ifndef EXCLUDE_FROM_XARALX
212 String_256
strFilename(rPath
);
213 strFilename
.toLower();
214 // See if the path points to a file (the easy case) or a directory
215 if (strFilename
[strFilename
.Length() - 1] == chPathSep
)
217 strFilename
.Remove(strFilename
.Length() - 1, 1);
220 struct _stat fileData
;
221 if (_stat((TCHAR
*) strFilename
, &fileData
))
225 ERROR3("Filename or path not found");
229 ERROR3("_stat() failed with an unknown error");
233 if (fileData
.st_mode
& _S_IFDIR
) // directory
236 // Make sure the directory is not the current one
237 TCHAR tchbuff
[_MAX_PATH
];
238 if (_getcwd(tchbuff
, _MAX_PATH
) == NULL
)
240 ERROR3("Can't get working directory");
243 if (strstr(_strlwr(tchbuff
), (TCHAR
*) strFilename
))
245 // change to upper dir (we should never attempt to delete the root directory!)
246 PathName
path(strFilename
);
247 if (_chdir((TCHAR
*) String_256(path
.GetLocation(FALSE
))))
249 ERROR3("Can't change directory");
253 // Try to remove it in the hope that it's empty
254 if (_rmdir((TCHAR
*) strFilename
) == -1)
256 if (errno
== ENOTEMPTY
|| errno
== EACCES
)
258 _finddata_t findData
;
259 String_256
strSearchPattern(strFilename
);
260 strSearchPattern
+= chPathSep
;
261 strSearchPattern
+= _T("*"); // add wildcard
262 INT32 hSearch
= _findfirst(strSearchPattern
, &findData
);
267 if (!(strcmp(findData
.name
, _T(".")) && strcmp(findData
.name
, _T(".."))))
268 continue; // skip this directory (.) or its parent (..)
269 String_256
strFoundFile(strFilename
);
270 strFoundFile
+= chPathSep
;
271 strFoundFile
+= findData
.name
;
272 RemoveRecursively(strFoundFile
);
274 while (_findnext(hSearch
, &findData
) == 0);
276 return (_rmdir((TCHAR
*) strFilename
) != -1);
280 return FALSE
; // probably invalid path
284 return TRUE
; // succedded
286 else if (fileData
.st_mode
& _S_IFREG
) // file
287 return (remove((TCHAR
*) strFilename
) != -1);