| 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 | message.SetTo(B_TRANSLATE("Registered file as disk device \"%s\"")); |
| 379 | message.ReplaceFirst("%s", path.Path()); |
| 380 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 381 | B_WIDTH_FROM_WIDEST, B_INFO_ALERT); |
| 382 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 383 | alert->Go(NULL); |
| 384 | } else { |
| 385 | message.SetTo(B_TRANSLATE("Registered file as disk device, but failed to get the device path.")); |
| 386 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 387 | B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); |
| 388 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 389 | alert->Go(NULL); |
| 390 | } |
| 391 | |
| 392 | return B_OK; |
| 393 | } |
| 394 | |
| 395 | |
| 396 | static status_t |
| 397 | unregister_file_disk_device(const char* fileNameOrID) |
| 398 | { |
| 399 | BString message; |
| 400 | |
| 401 | // try to parse the parameter as ID |
| 402 | char* numberEnd; |
| 403 | partition_id id = strtol(fileNameOrID, &numberEnd, 0); |
| 404 | BDiskDeviceRoster roster; |
| 405 | if (id >= 0 && numberEnd != fileNameOrID && *numberEnd == '\0') { |
| 406 | BDiskDevice device; |
| 407 | if (roster.GetDeviceWithID(id, &device) == B_OK && device.IsFile()) { |
| 408 | status_t error = roster.UnregisterFileDevice(id); |
| 409 | if (error != B_OK) { |
| 410 | message.SetTo(B_TRANSLATE("Failed to unregister file disk device.")); |
| 411 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 412 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 413 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 414 | alert->Go(NULL); |
| 415 | return error; |
| 416 | } |
| 417 | |
| 418 | message.SetTo(B_TRANSLATE("Unregistered file disk device.")); |
| 419 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 420 | B_WIDTH_FROM_WIDEST, B_INFO_ALERT); |
| 421 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 422 | alert->Go(NULL); |
| 423 | return B_OK; |
| 424 | } else { |
| 425 | message.SetTo(B_TRANSLATE("No file disk device found with the given ID, trying file \"%s\"")); |
| 426 | message.ReplaceFirst("%s", fileNameOrID); |
| 427 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 428 | B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); |
| 429 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 430 | alert->Go(NULL); |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | // the parameter must be a file name -- stat() it |
| 435 | struct stat st; |
| 436 | if (lstat(fileNameOrID, &st) != 0) { |
| 437 | status_t error = errno; |
| 438 | message.SetTo(B_TRANSLATE("Failed to stat() \"%s\"")); |
| 439 | message.ReplaceFirst("%s", fileNameOrID); |
| 440 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 441 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 442 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 443 | alert->Go(NULL); |
| 444 | return error; |
| 445 | } |
| 446 | |
| 447 | // remember the volume and node ID, so we can identify the file |
| 448 | // NOTE: There's a race condition -- we would need to open the file and |
| 449 | // keep it open to avoid it. |
| 450 | dev_t volumeID = st.st_dev; |
| 451 | ino_t nodeID = st.st_ino; |
| 452 | |
| 453 | // iterate through all file disk devices and try to find a match |
| 454 | BDiskDevice device; |
| 455 | while (roster.GetNextDevice(&device) == B_OK) { |
| 456 | if (!device.IsFile()) |
| 457 | continue; |
| 458 | |
| 459 | // get file path and stat it, same for the device path |
| 460 | BPath path; |
| 461 | bool isFilePath = true; |
| 462 | if ((device.GetFilePath(&path) == B_OK && lstat(path.Path(), &st) == 0 |
| 463 | && volumeID == st.st_dev && nodeID == st.st_ino) |
| 464 | || (isFilePath = false, false) |
| 465 | || (device.GetPath(&path) == B_OK && lstat(path.Path(), &st) == 0 |
| 466 | && volumeID == st.st_dev && nodeID == st.st_ino)) { |
| 467 | status_t error = roster.UnregisterFileDevice(device.ID()); |
| 468 | if (error != B_OK) { |
| 469 | message.SetTo(B_TRANSLATE("Failed to unregister file disk device \"%s\"")); |
| 470 | message.ReplaceFirst("%s", fileNameOrID); |
| 471 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 472 | B_WIDTH_FROM_WIDEST, B_STOP_ALERT); |
| 473 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 474 | alert->Go(NULL); |
| 475 | return error; |
| 476 | } |
| 477 | |
| 478 | message.SetTo(B_TRANSLATE("Unregistered file disk device \"%s\"")); |
| 479 | message.ReplaceFirst("%s", fileNameOrID); |
| 480 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 481 | B_WIDTH_FROM_WIDEST, B_INFO_ALERT); |
| 482 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 483 | alert->Go(NULL); |
| 484 | |
| 485 | return B_OK; |
| 486 | } |
| 487 | } |
| 488 | |
| 489 | message.SetTo(B_TRANSLATE("\"%s\" does not refer to a file disk device.")); |
| 490 | message.ReplaceFirst("%s", fileNameOrID); |
| 491 | BAlert* alert = new BAlert("error", message.String(), B_TRANSLATE("OK"), NULL, NULL, |
| 492 | B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); |
| 493 | alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); |
| 494 | alert->Go(NULL); |
| 495 | return B_BAD_VALUE; |
| 496 | } |
| 497 | |
| 498 | |