1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
---|
2 | /* ***** BEGIN LICENSE BLOCK ***** |
---|
3 | * Version: NPL 1.1/GPL 2.0/LGPL 2.1 |
---|
4 | * |
---|
5 | * The contents of this file are subject to the Netscape Public License |
---|
6 | * Version 1.1 (the "License"); you may not use this file except in |
---|
7 | * compliance with the License. You may obtain a copy of the License at |
---|
8 | * http://www.mozilla.org/NPL/ |
---|
9 | * |
---|
10 | * Software distributed under the License is distributed on an "AS IS" basis, |
---|
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
---|
12 | * for the specific language governing rights and limitations under the |
---|
13 | * License. |
---|
14 | * |
---|
15 | * The Original Code is mozilla.org code. |
---|
16 | * |
---|
17 | * The Initial Developer of the Original Code is |
---|
18 | * Netscape Communications Corporation. |
---|
19 | * Portions created by the Initial Developer are Copyright (C) 1998 |
---|
20 | * the Initial Developer. All Rights Reserved. |
---|
21 | * |
---|
22 | * Contributor(s): |
---|
23 | * |
---|
24 | * Alternatively, the contents of this file may be used under the terms of |
---|
25 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
---|
26 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
---|
27 | * in which case the provisions of the GPL or the LGPL are applicable instead |
---|
28 | * of those above. If you wish to allow use of your version of this file only |
---|
29 | * under the terms of either the GPL or the LGPL, and not to allow others to |
---|
30 | * use your version of this file under the terms of the NPL, indicate your |
---|
31 | * decision by deleting the provisions above and replace them with the notice |
---|
32 | * and other provisions required by the GPL or the LGPL. If you do not delete |
---|
33 | * the provisions above, a recipient may use your version of this file under |
---|
34 | * the terms of any one of the NPL, the GPL or the LGPL. |
---|
35 | * |
---|
36 | * ***** END LICENSE BLOCK ***** */ |
---|
37 | |
---|
38 | // This file is included by nsFileSpec.cpp, and includes the Unix-specific |
---|
39 | // implementations. |
---|
40 | |
---|
41 | #include <sys/stat.h> |
---|
42 | #include <sys/param.h> |
---|
43 | #include <errno.h> |
---|
44 | #include <dirent.h> |
---|
45 | #include <unistd.h> |
---|
46 | #include <stdlib.h> |
---|
47 | #include <limits.h> |
---|
48 | #include "nsError.h" |
---|
49 | #include "prio.h" /* for PR_Rename */ |
---|
50 | |
---|
51 | // BeOS specific headers |
---|
52 | #include <Entry.h> |
---|
53 | #include <Path.h> |
---|
54 | #include <Volume.h> |
---|
55 | |
---|
56 | //---------------------------------------------------------------------------------------- |
---|
57 | void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs) |
---|
58 | // Canonify, make absolute, and check whether directories exist |
---|
59 | //---------------------------------------------------------------------------------------- |
---|
60 | { |
---|
61 | if (ioPath.IsEmpty()) |
---|
62 | return; |
---|
63 | if (inMakeDirs) |
---|
64 | { |
---|
65 | const mode_t mode = 0700; |
---|
66 | nsFileSpecHelpers::MakeAllDirectories((const char*)ioPath, mode); |
---|
67 | } |
---|
68 | char buffer[MAXPATHLEN]; |
---|
69 | errno = 0; |
---|
70 | *buffer = '\0'; |
---|
71 | BEntry e((const char *)ioPath, true); |
---|
72 | BPath p; |
---|
73 | e.GetPath(&p); |
---|
74 | ioPath = p.Path(); |
---|
75 | } // nsFileSpecHelpers::Canonify |
---|
76 | |
---|
77 | //---------------------------------------------------------------------------------------- |
---|
78 | void nsFileSpec::SetLeafName(const char* inLeafName) |
---|
79 | //---------------------------------------------------------------------------------------- |
---|
80 | { |
---|
81 | mPath.LeafReplace('/', inLeafName); |
---|
82 | } // nsFileSpec::SetLeafName |
---|
83 | |
---|
84 | //---------------------------------------------------------------------------------------- |
---|
85 | char* nsFileSpec::GetLeafName() const |
---|
86 | //---------------------------------------------------------------------------------------- |
---|
87 | { |
---|
88 | return mPath.GetLeaf('/'); |
---|
89 | } // nsFileSpec::GetLeafName |
---|
90 | |
---|
91 | //---------------------------------------------------------------------------------------- |
---|
92 | PRBool nsFileSpec::Exists() const |
---|
93 | //---------------------------------------------------------------------------------------- |
---|
94 | { |
---|
95 | struct stat st; |
---|
96 | return !mPath.IsEmpty() && 0 == stat(mPath, &st); |
---|
97 | } // nsFileSpec::Exists |
---|
98 | |
---|
99 | //---------------------------------------------------------------------------------------- |
---|
100 | void nsFileSpec::GetModDate(TimeStamp& outStamp) const |
---|
101 | //---------------------------------------------------------------------------------------- |
---|
102 | { |
---|
103 | struct stat st; |
---|
104 | if (!mPath.IsEmpty() && stat(mPath, &st) == 0) |
---|
105 | outStamp = st.st_mtime; |
---|
106 | else |
---|
107 | outStamp = 0; |
---|
108 | } // nsFileSpec::GetModDate |
---|
109 | |
---|
110 | //---------------------------------------------------------------------------------------- |
---|
111 | PRUint32 nsFileSpec::GetFileSize() const |
---|
112 | //---------------------------------------------------------------------------------------- |
---|
113 | { |
---|
114 | struct stat st; |
---|
115 | if (!mPath.IsEmpty() && stat(mPath, &st) == 0) |
---|
116 | return (PRUint32)st.st_size; |
---|
117 | return 0; |
---|
118 | } // nsFileSpec::GetFileSize |
---|
119 | |
---|
120 | //---------------------------------------------------------------------------------------- |
---|
121 | PRBool nsFileSpec::IsFile() const |
---|
122 | //---------------------------------------------------------------------------------------- |
---|
123 | { |
---|
124 | struct stat st; |
---|
125 | return !mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISREG(st.st_mode); |
---|
126 | } // nsFileSpec::IsFile |
---|
127 | |
---|
128 | //---------------------------------------------------------------------------------------- |
---|
129 | PRBool nsFileSpec::IsDirectory() const |
---|
130 | //---------------------------------------------------------------------------------------- |
---|
131 | { |
---|
132 | struct stat st; |
---|
133 | return !mPath.IsEmpty() && 0 == stat(mPath, &st) && S_ISDIR(st.st_mode); |
---|
134 | } // nsFileSpec::IsDirectory |
---|
135 | |
---|
136 | //---------------------------------------------------------------------------------------- |
---|
137 | PRBool nsFileSpec::IsHidden() const |
---|
138 | //---------------------------------------------------------------------------------------- |
---|
139 | { |
---|
140 | PRBool hidden = PR_TRUE; |
---|
141 | char *leafname = GetLeafName(); |
---|
142 | if (nsnull != leafname) |
---|
143 | { |
---|
144 | if ((!strcmp(leafname, ".")) || (!strcmp(leafname, ".."))) |
---|
145 | { |
---|
146 | hidden = PR_FALSE; |
---|
147 | } |
---|
148 | nsCRT::free(leafname); |
---|
149 | } |
---|
150 | return hidden; |
---|
151 | } // nsFileSpec::IsHidden |
---|
152 | |
---|
153 | //---------------------------------------------------------------------------------------- |
---|
154 | PRBool nsFileSpec::IsSymlink() const |
---|
155 | //---------------------------------------------------------------------------------------- |
---|
156 | { |
---|
157 | struct stat st; |
---|
158 | if (!mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISLNK(st.st_mode)) |
---|
159 | return PR_TRUE; |
---|
160 | |
---|
161 | return PR_FALSE; |
---|
162 | } // nsFileSpec::IsSymlink |
---|
163 | |
---|
164 | //---------------------------------------------------------------------------------------- |
---|
165 | nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased) |
---|
166 | //---------------------------------------------------------------------------------------- |
---|
167 | { |
---|
168 | wasAliased = PR_FALSE; |
---|
169 | |
---|
170 | char resolvedPath[MAXPATHLEN]; |
---|
171 | int charCount = readlink(mPath, (char*)&resolvedPath, MAXPATHLEN); |
---|
172 | if (0 < charCount) |
---|
173 | { |
---|
174 | if (MAXPATHLEN > charCount) |
---|
175 | resolvedPath[charCount] = '\0'; |
---|
176 | |
---|
177 | wasAliased = PR_TRUE; |
---|
178 | /* if it's not an absolute path, |
---|
179 | replace the leaf with what got resolved */ |
---|
180 | if (resolvedPath[0] != '/') { |
---|
181 | SetLeafName(resolvedPath); |
---|
182 | } |
---|
183 | else { |
---|
184 | mPath = (char*)resolvedPath; |
---|
185 | } |
---|
186 | |
---|
187 | BEntry e((const char *)mPath, true); // traverse symlink |
---|
188 | BPath p; |
---|
189 | status_t err; |
---|
190 | err = e.GetPath(&p); |
---|
191 | NS_ASSERTION(err == B_OK, "realpath failed"); |
---|
192 | |
---|
193 | const char* canonicalPath = p.Path(); |
---|
194 | if(err == B_OK) |
---|
195 | mPath = (char*)canonicalPath; |
---|
196 | else |
---|
197 | return NS_ERROR_FAILURE; |
---|
198 | } |
---|
199 | return NS_OK; |
---|
200 | } // nsFileSpec::ResolveSymlink |
---|
201 | |
---|
202 | //---------------------------------------------------------------------------------------- |
---|
203 | void nsFileSpec::GetParent(nsFileSpec& outSpec) const |
---|
204 | //---------------------------------------------------------------------------------------- |
---|
205 | { |
---|
206 | outSpec.mPath = mPath; |
---|
207 | char* chars = (char*)outSpec.mPath; |
---|
208 | chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any |
---|
209 | char* cp = strrchr(chars, '/'); |
---|
210 | if (cp++) |
---|
211 | outSpec.mPath.SetLength(cp - chars); // truncate. |
---|
212 | } // nsFileSpec::GetParent |
---|
213 | |
---|
214 | //---------------------------------------------------------------------------------------- |
---|
215 | void nsFileSpec::operator += (const char* inRelativePath) |
---|
216 | //---------------------------------------------------------------------------------------- |
---|
217 | { |
---|
218 | if (!inRelativePath || mPath.IsEmpty()) |
---|
219 | return; |
---|
220 | |
---|
221 | char endChar = mPath[(int)(strlen(mPath) - 1)]; |
---|
222 | if (endChar == '/') |
---|
223 | mPath += "x"; |
---|
224 | else |
---|
225 | mPath += "/x"; |
---|
226 | SetLeafName(inRelativePath); |
---|
227 | } // nsFileSpec::operator += |
---|
228 | |
---|
229 | //---------------------------------------------------------------------------------------- |
---|
230 | void nsFileSpec::CreateDirectory(int mode) |
---|
231 | //---------------------------------------------------------------------------------------- |
---|
232 | { |
---|
233 | // Note that mPath is canonical! |
---|
234 | if (mPath.IsEmpty()) |
---|
235 | return; |
---|
236 | mkdir(mPath, mode); |
---|
237 | } // nsFileSpec::CreateDirectory |
---|
238 | |
---|
239 | //---------------------------------------------------------------------------------------- |
---|
240 | void nsFileSpec::Delete(PRBool inRecursive) const |
---|
241 | // To check if this worked, call Exists() afterwards, see? |
---|
242 | //---------------------------------------------------------------------------------------- |
---|
243 | { |
---|
244 | if (IsDirectory()) |
---|
245 | { |
---|
246 | if (inRecursive) |
---|
247 | { |
---|
248 | for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++) |
---|
249 | { |
---|
250 | nsFileSpec& child = (nsFileSpec&)i; |
---|
251 | child.Delete(inRecursive); |
---|
252 | } |
---|
253 | } |
---|
254 | rmdir(mPath); |
---|
255 | } |
---|
256 | else if (!mPath.IsEmpty()) |
---|
257 | remove(mPath); |
---|
258 | } // nsFileSpec::Delete |
---|
259 | |
---|
260 | //---------------------------------------------------------------------------------------- |
---|
261 | void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const |
---|
262 | //---------------------------------------------------------------------------------------- |
---|
263 | { |
---|
264 | if (IsDirectory()) |
---|
265 | { |
---|
266 | if (!(newDir.Exists())) |
---|
267 | { |
---|
268 | newDir.CreateDirectory(); |
---|
269 | } |
---|
270 | |
---|
271 | for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++) |
---|
272 | { |
---|
273 | nsFileSpec& child = (nsFileSpec&)i; |
---|
274 | |
---|
275 | if (child.IsDirectory()) |
---|
276 | { |
---|
277 | nsFileSpec tmpDirSpec(newDir); |
---|
278 | |
---|
279 | char *leafname = child.GetLeafName(); |
---|
280 | tmpDirSpec += leafname; |
---|
281 | nsCRT::free(leafname); |
---|
282 | |
---|
283 | child.RecursiveCopy(tmpDirSpec); |
---|
284 | } |
---|
285 | else |
---|
286 | { |
---|
287 | child.RecursiveCopy(newDir); |
---|
288 | } |
---|
289 | } |
---|
290 | } |
---|
291 | else if (!mPath.IsEmpty()) |
---|
292 | { |
---|
293 | nsFileSpec& filePath = (nsFileSpec&) *this; |
---|
294 | |
---|
295 | if (!(newDir.Exists())) |
---|
296 | { |
---|
297 | newDir.CreateDirectory(); |
---|
298 | } |
---|
299 | |
---|
300 | filePath.CopyToDir(newDir); |
---|
301 | } |
---|
302 | } // nsFileSpec::RecursiveCopy |
---|
303 | |
---|
304 | //---------------------------------------------------------------------------------------- |
---|
305 | nsresult nsFileSpec::Truncate(PRInt32 offset) const |
---|
306 | //---------------------------------------------------------------------------------------- |
---|
307 | { |
---|
308 | char* Path = nsCRT::strdup(mPath); |
---|
309 | |
---|
310 | int rv = truncate(Path, offset) ; |
---|
311 | |
---|
312 | nsCRT::free(Path) ; |
---|
313 | |
---|
314 | if(!rv) |
---|
315 | return NS_OK ; |
---|
316 | else |
---|
317 | return NS_ERROR_FAILURE ; |
---|
318 | } // nsFileSpec::Truncate |
---|
319 | |
---|
320 | //---------------------------------------------------------------------------------------- |
---|
321 | nsresult nsFileSpec::Rename(const char* inNewName) |
---|
322 | //---------------------------------------------------------------------------------------- |
---|
323 | { |
---|
324 | // This function should not be used to move a file on disk. |
---|
325 | if (mPath.IsEmpty() || strchr(inNewName, '/')) |
---|
326 | return NS_FILE_FAILURE; |
---|
327 | |
---|
328 | char* oldPath = nsCRT::strdup(mPath); |
---|
329 | |
---|
330 | SetLeafName(inNewName); |
---|
331 | |
---|
332 | if (PR_Rename(oldPath, mPath) != NS_OK) |
---|
333 | { |
---|
334 | // Could not rename, set back to the original. |
---|
335 | mPath = oldPath; |
---|
336 | return NS_FILE_FAILURE; |
---|
337 | } |
---|
338 | |
---|
339 | nsCRT::free(oldPath); |
---|
340 | |
---|
341 | return NS_OK; |
---|
342 | } // nsFileSpec::Rename |
---|
343 | |
---|
344 | //---------------------------------------------------------------------------------------- |
---|
345 | static int CrudeFileCopy(const char* in, const char* out) |
---|
346 | //---------------------------------------------------------------------------------------- |
---|
347 | { |
---|
348 | struct stat in_stat; |
---|
349 | int stat_result = -1; |
---|
350 | |
---|
351 | char buf [1024]; |
---|
352 | FILE *ifp, *ofp; |
---|
353 | int rbytes, wbytes; |
---|
354 | |
---|
355 | if (!in || !out) |
---|
356 | return -1; |
---|
357 | |
---|
358 | stat_result = stat (in, &in_stat); |
---|
359 | |
---|
360 | ifp = fopen (in, "r"); |
---|
361 | if (!ifp) |
---|
362 | { |
---|
363 | return -1; |
---|
364 | } |
---|
365 | |
---|
366 | ofp = fopen (out, "w"); |
---|
367 | if (!ofp) |
---|
368 | { |
---|
369 | fclose (ifp); |
---|
370 | return -1; |
---|
371 | } |
---|
372 | |
---|
373 | while ((rbytes = fread (buf, 1, sizeof(buf), ifp)) > 0) |
---|
374 | { |
---|
375 | while (rbytes > 0) |
---|
376 | { |
---|
377 | if ( (wbytes = fwrite (buf, 1, rbytes, ofp)) < 0 ) |
---|
378 | { |
---|
379 | fclose (ofp); |
---|
380 | fclose (ifp); |
---|
381 | unlink(out); |
---|
382 | return -1; |
---|
383 | } |
---|
384 | rbytes -= wbytes; |
---|
385 | } |
---|
386 | } |
---|
387 | fclose (ofp); |
---|
388 | fclose (ifp); |
---|
389 | |
---|
390 | if (stat_result == 0) |
---|
391 | chmod (out, in_stat.st_mode & 0777); |
---|
392 | |
---|
393 | return 0; |
---|
394 | } // nsFileSpec::Rename |
---|
395 | |
---|
396 | //---------------------------------------------------------------------------------------- |
---|
397 | nsresult nsFileSpec::CopyToDir(const nsFileSpec& inParentDirectory) const |
---|
398 | //---------------------------------------------------------------------------------------- |
---|
399 | { |
---|
400 | // We can only copy into a directory, and (for now) can not copy entire directories |
---|
401 | nsresult result = NS_FILE_FAILURE; |
---|
402 | |
---|
403 | if (inParentDirectory.IsDirectory() && (! IsDirectory() ) ) |
---|
404 | { |
---|
405 | char *leafname = GetLeafName(); |
---|
406 | nsSimpleCharString destPath(inParentDirectory.GetCString()); |
---|
407 | destPath += "/"; |
---|
408 | destPath += leafname; |
---|
409 | nsCRT::free(leafname); |
---|
410 | result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), destPath)); |
---|
411 | } |
---|
412 | return result; |
---|
413 | } // nsFileSpec::CopyToDir |
---|
414 | |
---|
415 | //---------------------------------------------------------------------------------------- |
---|
416 | nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory) |
---|
417 | //---------------------------------------------------------------------------------------- |
---|
418 | { |
---|
419 | // We can only copy into a directory, and (for now) can not copy entire directories |
---|
420 | nsresult result = NS_FILE_FAILURE; |
---|
421 | |
---|
422 | if (inNewParentDirectory.IsDirectory() && !IsDirectory()) |
---|
423 | { |
---|
424 | char *leafname = GetLeafName(); |
---|
425 | nsSimpleCharString destPath(inNewParentDirectory.GetCString()); |
---|
426 | destPath += "/"; |
---|
427 | destPath += leafname; |
---|
428 | nsCRT::free(leafname); |
---|
429 | |
---|
430 | result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), (const char*)destPath)); |
---|
431 | if (result == NS_OK) |
---|
432 | { |
---|
433 | // cast to fix const-ness |
---|
434 | ((nsFileSpec*)this)->Delete(PR_FALSE); |
---|
435 | |
---|
436 | *this = inNewParentDirectory + GetLeafName(); |
---|
437 | } |
---|
438 | } |
---|
439 | return result; |
---|
440 | } |
---|
441 | |
---|
442 | //---------------------------------------------------------------------------------------- |
---|
443 | nsresult nsFileSpec::Execute(const char* inArgs ) const |
---|
444 | //---------------------------------------------------------------------------------------- |
---|
445 | { |
---|
446 | nsresult result = NS_FILE_FAILURE; |
---|
447 | |
---|
448 | if (!mPath.IsEmpty() && !IsDirectory()) |
---|
449 | { |
---|
450 | nsSimpleCharString fileNameWithArgs = mPath + " " + inArgs; |
---|
451 | result = NS_FILE_RESULT(system(fileNameWithArgs)); |
---|
452 | } |
---|
453 | |
---|
454 | return result; |
---|
455 | |
---|
456 | } // nsFileSpec::Execute |
---|
457 | |
---|
458 | //---------------------------------------------------------------------------------------- |
---|
459 | PRInt64 nsFileSpec::GetDiskSpaceAvailable() const |
---|
460 | //---------------------------------------------------------------------------------------- |
---|
461 | { |
---|
462 | char curdir [MAXPATHLEN]; |
---|
463 | if (!mPath || !*mPath) |
---|
464 | { |
---|
465 | (void) getcwd(curdir, MAXPATHLEN); |
---|
466 | if (!curdir) |
---|
467 | return ULONGLONG_MAX; /* hope for the best as we did in cheddar */ |
---|
468 | } |
---|
469 | else |
---|
470 | sprintf(curdir, "%.200s", (const char*)mPath); |
---|
471 | |
---|
472 | BEntry e(curdir); |
---|
473 | if(e.InitCheck() != B_OK) |
---|
474 | return ULONGLONG_MAX; /* hope for the best as we did in cheddar */ |
---|
475 | entry_ref ref; |
---|
476 | e.GetRef(&ref); |
---|
477 | BVolume v(ref.device); |
---|
478 | |
---|
479 | #ifdef DEBUG_DISK_SPACE |
---|
480 | printf("DiskSpaceAvailable: %d bytes\n", space); |
---|
481 | #endif |
---|
482 | return v.FreeBytes(); |
---|
483 | } // nsFileSpec::GetDiskSpace() |
---|
484 | |
---|
485 | //======================================================================================== |
---|
486 | // nsDirectoryIterator |
---|
487 | //======================================================================================== |
---|
488 | |
---|
489 | //---------------------------------------------------------------------------------------- |
---|
490 | nsDirectoryIterator::nsDirectoryIterator( |
---|
491 | const nsFileSpec& inDirectory |
---|
492 | , PRBool resolveSymlinks) |
---|
493 | //---------------------------------------------------------------------------------------- |
---|
494 | : mCurrent(inDirectory) |
---|
495 | , mStarting(inDirectory) |
---|
496 | , mExists(PR_FALSE) |
---|
497 | , mDir(nsnull) |
---|
498 | , mResoveSymLinks(resolveSymlinks) |
---|
499 | { |
---|
500 | mStarting += "sysygy"; // save off the starting directory |
---|
501 | mCurrent += "sysygy"; // prepare the path for SetLeafName |
---|
502 | mDir = opendir((const char*)nsFilePath(inDirectory)); |
---|
503 | ++(*this); |
---|
504 | } // nsDirectoryIterator::nsDirectoryIterator |
---|
505 | |
---|
506 | //---------------------------------------------------------------------------------------- |
---|
507 | nsDirectoryIterator::~nsDirectoryIterator() |
---|
508 | //---------------------------------------------------------------------------------------- |
---|
509 | { |
---|
510 | if (mDir) |
---|
511 | closedir(mDir); |
---|
512 | } // nsDirectoryIterator::nsDirectoryIterator |
---|
513 | |
---|
514 | //---------------------------------------------------------------------------------------- |
---|
515 | nsDirectoryIterator& nsDirectoryIterator::operator ++ () |
---|
516 | //---------------------------------------------------------------------------------------- |
---|
517 | { |
---|
518 | mExists = PR_FALSE; |
---|
519 | if (!mDir) |
---|
520 | return *this; |
---|
521 | char* dot = "."; |
---|
522 | char* dotdot = ".."; |
---|
523 | struct dirent* entry = readdir(mDir); |
---|
524 | if (entry && strcmp(entry->d_name, dot) == 0) |
---|
525 | entry = readdir(mDir); |
---|
526 | if (entry && strcmp(entry->d_name, dotdot) == 0) |
---|
527 | entry = readdir(mDir); |
---|
528 | if (entry) |
---|
529 | { |
---|
530 | mExists = PR_TRUE; |
---|
531 | mCurrent = mStarting; // restore mCurrent to be the starting directory. ResolveSymlink() may have taken us to another directory |
---|
532 | mCurrent.SetLeafName(entry->d_name); |
---|
533 | if (mResoveSymLinks) |
---|
534 | { |
---|
535 | PRBool ignore; |
---|
536 | mCurrent.ResolveSymlink(ignore); |
---|
537 | } |
---|
538 | } |
---|
539 | return *this; |
---|
540 | } // nsDirectoryIterator::operator ++ |
---|
541 | |
---|
542 | //---------------------------------------------------------------------------------------- |
---|
543 | nsDirectoryIterator& nsDirectoryIterator::operator -- () |
---|
544 | //---------------------------------------------------------------------------------------- |
---|
545 | { |
---|
546 | return ++(*this); // can't do it backwards. |
---|
547 | } // nsDirectoryIterator::operator -- |
---|