Changeset 44286 in vbox
- Timestamp:
- Jan 14, 2013 1:24:13 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 83194
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/path/RTPathRmCmd.cpp
r44279 r44286 53 53 54 54 /** The max directory entry size. */ 55 #define RTPATHRM_DIR_MAX_ENTRY_SIZE 409655 #define RTPATHRM_DIR_MAX_ENTRY_SIZE (sizeof(RTDIRENTRYEX) + 4096) 56 56 57 57 … … 253 253 * @param pDirEntry Pointer to a directory entry buffer that is 254 254 * RTPATHRM_DIR_MAX_ENTRY_SIZE bytes big. 255 * @param pObjInfo Pointer the FS object info for the directory. 256 * This will be modified. 257 */ 258 static int rtPathRmRecursive(PRTPATHRMCMDOPTS pOpts, char *pszPath, size_t cchPath, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo) 255 */ 256 static int rtPathRmRecursive(PRTPATHRMCMDOPTS pOpts, char *pszPath, size_t cchPath, PRTDIRENTRYEX pDirEntry) 259 257 { 260 258 /* … … 283 281 */ 284 282 size_t cbEntry = RTPATHRM_DIR_MAX_ENTRY_SIZE; 285 rc = RTDirRead (hDir, pDirEntry, &cbEntry);283 rc = RTDirReadEx(hDir, pDirEntry, &cbEntry, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 286 284 if (rc == VERR_NO_MORE_FILES) 287 285 { 286 /* 287 * Reached the end of the directory. 288 */ 288 289 pszPath[cchPath] = '\0'; 289 290 rc = RTDirClose(hDir); … … 297 298 return rcRet; 298 299 } 300 299 301 if (RT_FAILURE(rc)) 300 302 { … … 320 322 321 323 /* 322 * Just query the full path info as we'll need it.323 */324 rc = RTPathQueryInfoEx(pszPath, pObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK);325 if (RT_FAILURE(rc))326 {327 rc = rtPathRmError(pOpts, pszPath, rc, "RTPathQueryInfoEx failed on '%s': %Rrc", pszPath, rc);328 if (RT_SUCCESS(rcRet))329 rcRet = rc;330 }331 332 /*333 324 * Take action according to the type. 334 325 */ 335 switch (p ObjInfo->Attr.fMode & RTFS_TYPE_MASK)326 switch (pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK) 336 327 { 337 328 case RTFS_TYPE_FILE: 338 rc = rtPathRmOneFile(pOpts, pszPath, pObjInfo);329 rc = rtPathRmOneFile(pOpts, pszPath, &pDirEntry->Info); 339 330 break; 340 331 341 332 case RTFS_TYPE_DIRECTORY: 342 rc = rtPathRmRecursive(pOpts, pszPath, cchPath , pDirEntry, pObjInfo);333 rc = rtPathRmRecursive(pOpts, pszPath, cchPath + pDirEntry->cbName, pDirEntry); 343 334 break; 344 335 … … 351 342 case RTFS_TYPE_DEV_BLOCK: 352 343 case RTFS_TYPE_SOCKET: 353 rc = rtPathRmOneFile(pOpts, pszPath, pObjInfo);344 rc = rtPathRmOneFile(pOpts, pszPath, &pDirEntry->Info); 354 345 break; 355 346 … … 357 348 default: 358 349 rc = rtPathRmError(pOpts, pszPath, VERR_UNEXPECTED_FS_OBJ_TYPE, 359 "Object '%s' has an unknown file type: %o\n", pszPath, pObjInfo->Attr.fMode & RTFS_TYPE_MASK); 350 "Object '%s' has an unknown file type: %o\n", 351 pszPath, pDirEntry->Info.Attr.fMode & RTFS_TYPE_MASK); 360 352 break; 361 353 } … … 364 356 } 365 357 358 /* 359 * Some error occured, close and return. 360 */ 366 361 RTDirClose(hDir); 367 362 return rc; 368 363 } 369 364 370 371 365 /** 372 * Remove one userspecified file or directory.366 * Validates the specified file or directory. 373 367 * 374 368 * @returns IPRT status code, errors go via rtPathRmError. … … 376 370 * @param pszPath The path to the file, directory, whatever. 377 371 */ 372 static int rtPathRmOneValidate(PRTPATHRMCMDOPTS pOpts, const char *pszPath) 373 { 374 /* 375 * RTPathFilename doesn't do the trailing slash thing the way we need it to. 376 * E.g. both '..' and '../' should be rejected. 377 */ 378 size_t cchPath = strlen(pszPath); 379 while (cchPath > 0 && RTPATH_IS_SLASH(pszPath[cchPath - 1])) 380 cchPath--; 381 382 if ( ( cchPath == 0 383 || 0 /** @todo drive letter + UNC crap */) 384 && pOpts->fPreserveRoot) 385 return rtPathRmError(pOpts, pszPath, VERR_CANT_DELETE_DIRECTORY, "Cannot remove root directory ('%s').\n", pszPath); 386 387 size_t offLast = cchPath - 1; 388 while (offLast > 0 && !RTPATH_IS_SEP(pszPath[offLast - 1])) 389 offLast--; 390 391 size_t cchLast = cchPath - offLast; 392 if ( pszPath[offLast] == '.' 393 && ( cchLast == 1 394 || (cchLast == 2 && pszPath[offLast + 1] == '.'))) 395 return rtPathRmError(pOpts, pszPath, VERR_CANT_DELETE_DIRECTORY, "Cannot remove special directory '%s'.\n", pszPath); 396 397 return VINF_SUCCESS; 398 } 399 400 401 /** 402 * Remove one user specified file or directory. 403 * 404 * @returns IPRT status code, errors go via rtPathRmError. 405 * @param pOpts The RM options. 406 * @param pszPath The path to the file, directory, whatever. 407 */ 378 408 static int rtPathRmOne(PRTPATHRMCMDOPTS pOpts, const char *pszPath) 379 409 { 380 410 /* 381 * Refuse to remove '.' and '..'. 382 */ 383 const char *pszFilename = RTPathFilename(pszPath); 384 if ( pszFilename[0] == '.' 385 && ( pszFilename[1] == '\0' 386 || (pszFilename[1] == '.' && pszFilename[2] == '\0'))) 387 return rtPathRmError(pOpts, pszPath, VERR_CANT_DELETE_DIRECTORY, "Cannot remove directory '%s'.\n", pszPath); 411 * RM refuses to delete some directories. 412 */ 413 int rc = rtPathRmOneValidate(pOpts, pszPath); 414 if (RT_FAILURE(rc)) 415 return rc; 388 416 389 417 /* … … 391 419 */ 392 420 RTFSOBJINFO ObjInfo; 393 intrc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK);421 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, RTPATH_F_ON_LINK); 394 422 if (RT_FAILURE(rc)) 395 423 { … … 417 445 union 418 446 { 419 RTDIRENTRY Core;420 uint8_t abPadding[RTPATHRM_DIR_MAX_ENTRY_SIZE];447 RTDIRENTRYEX Core; 448 uint8_t abPadding[RTPATHRM_DIR_MAX_ENTRY_SIZE]; 421 449 } DirEntry; 422 450 423 return rtPathRmRecursive(pOpts, szPath, strlen(szPath), &DirEntry.Core , &ObjInfo);451 return rtPathRmRecursive(pOpts, szPath, strlen(szPath), &DirEntry.Core); 424 452 } 425 453 if (pOpts->fDirsAndOther)
Note:
See TracChangeset
for help on using the changeset viewer.