| 332 | static status_t |
| 333 | register_file_disk_device(const char* fileName) |
| 334 | { |
| 335 | BString message; |
| 336 | |
| 337 | struct stat st; |
| 338 | if (lstat(fileName, &st) != 0) { |
| 339 | status_t error = errno; |
| 340 | |
| 341 | message.SetTo(B_TRANSLATE("Failed to stat() %s")); |
| 342 | message.ReplaceFirst("%s", fileName); |
| 343 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 344 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 345 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 346 | alert->Go(NULL); |
| 347 | return error; |
| 348 | } |
| 349 | |
| 350 | if (!S_ISREG(st.st_mode)) { |
| 351 | message.SetTo(B_TRANSLATE("%s is not a regular file.")); |
| 352 | message.ReplaceFirst("%s", fileName); |
| 353 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 354 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 355 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 356 | alert->Go(NULL); |
| 357 | return B_BAD_VALUE; |
| 358 | } |
| 359 | |
| 360 | // register the file |
| 361 | BDiskDeviceRoster roster; |
| 362 | partition_id id = roster.RegisterFileDevice(fileName); |
| 363 | if (id < 0) { |
| 364 | message.SetTo(B_TRANSLATE("Failed to register file disk device: %s")); |
| 365 | message.ReplaceFirst("%s", fileName); |
| 366 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 367 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 368 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 369 | alert->Go(NULL); |
| 370 | return id; |
| 371 | } |
| 372 | |
| 373 | // print the success message (get the device path) |
| 374 | BDiskDevice device; |
| 375 | BPath path; |
| 376 | if (roster.GetDeviceWithID(id, &device) == B_OK |
| 377 | && device.GetPath(&path) == B_OK) { |
| 378 | } else { |
| 379 | message.SetTo(B_TRANSLATE("Registered file as disk device, but failed to get the device path.")); |
| 380 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 381 | B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); |
| 382 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 383 | alert->Go(NULL); |
| 384 | } |
| 385 | |
| 386 | return B_OK; |
| 387 | } |
| 388 | |
| 389 | |
| 390 | static status_t |
| 391 | unregister_file_disk_device(const char* fileNameOrID) |
| 392 | { |
| 393 | BString message; |
| 394 | |
| 395 | // try to parse the parameter as ID |
| 396 | char* numberEnd; |
| 397 | partition_id id = strtol(fileNameOrID, &numberEnd, 0); |
| 398 | BDiskDeviceRoster roster; |
| 399 | if (id >= 0 && numberEnd != fileNameOrID && *numberEnd == '\0') { |
| 400 | BDiskDevice device; |
| 401 | if (roster.GetDeviceWithID(id, &device) == B_OK && device.IsFile()) { |
| 402 | status_t error = roster.UnregisterFileDevice(id); |
| 403 | if (error != B_OK) { |
| 404 | message.SetTo(B_TRANSLATE("Failed to unregister file disk device.")); |
| 405 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 406 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 407 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 408 | alert->Go(NULL); |
| 409 | return error; |
| 410 | } |
| 411 | return B_OK; |
| 412 | } else { |
| 413 | message.SetTo(B_TRANSLATE("No file disk device found with the given ID, trying file %s")); |
| 414 | message.ReplaceFirst("%s", fileNameOrID); |
| 415 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 416 | B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); |
| 417 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 418 | alert->Go(NULL); |
| 419 | } |
| 420 | } |
| 421 | |
| 422 | // the parameter must be a file name -- stat() it |
| 423 | struct stat st; |
| 424 | if (lstat(fileNameOrID, &st) != 0) { |
| 425 | status_t error = errno; |
| 426 | message.SetTo(B_TRANSLATE("Failed to stat() %s")); |
| 427 | message.ReplaceFirst("%s", fileNameOrID); |
| 428 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 429 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 430 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 431 | alert->Go(NULL); |
| 432 | return error; |
| 433 | } |
| 434 | |
| 435 | // remember the volume and node ID, so we can identify the file |
| 436 | // NOTE: There's a race condition -- we would need to open the file and |
| 437 | // keep it open to avoid it. |
| 438 | dev_t volumeID = st.st_dev; |
| 439 | ino_t nodeID = st.st_ino; |
| 440 | |
| 441 | // iterate through all file disk devices and try to find a match |
| 442 | BDiskDevice device; |
| 443 | while (roster.GetNextDevice(&device) == B_OK) { |
| 444 | if (!device.IsFile()) |
| 445 | continue; |
| 446 | |
| 447 | // get file path and stat it, same for the device path |
| 448 | BPath path; |
| 449 | bool isFilePath = true; |
| 450 | if ((device.GetFilePath(&path) == B_OK && lstat(path.Path(), &st) == 0 |
| 451 | && volumeID == st.st_dev && nodeID == st.st_ino) |
| 452 | || (isFilePath = false, false) |
| 453 | || (device.GetPath(&path) == B_OK && lstat(path.Path(), &st) == 0 |
| 454 | && volumeID == st.st_dev && nodeID == st.st_ino)) { |
| 455 | status_t error = roster.UnregisterFileDevice(device.ID()); |
| 456 | if (error != B_OK) { |
| 457 | message.SetTo(B_TRANSLATE("Failed to unregister file disk device %s")); |
| 458 | message.ReplaceFirst("%s", fileNameOrID); |
| 459 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 460 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 461 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 462 | alert->Go(NULL); |
| 463 | return error; |
| 464 | } |
| 465 | return B_OK; |
| 466 | } |
| 467 | } |
| 468 | |
| 469 | message.SetTo(B_TRANSLATE("%s does not refer to a file disk device.")); |
| 470 | message.ReplaceFirst("%s", fileNameOrID); |
| 471 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 472 | B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); |
| 473 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 474 | alert->Go(NULL); |
| 475 | return B_BAD_VALUE; |
| 476 | } |
| 477 | |
| 478 | |