| | 522 | static void |
| | 523 | sfprov_timespec_from_ftime(RTTIMESPEC *ts, timestruc_t time) |
| | 524 | { |
| | 525 | uint64_t nanosec = 1000000000 * time.tv_sec + time.tv_nsec; |
| | 526 | RTTimeSpecSetNano(ts, nanosec); |
| | 527 | } |
| | 528 | |
| | 529 | int |
| | 530 | sfprov_set_attr( |
| | 531 | sfp_mount_t *mnt, |
| | 532 | char *path, |
| | 533 | uint_t mask, |
| | 534 | mode_t mode, |
| | 535 | timestruc_t atime, |
| | 536 | timestruc_t mtime, |
| | 537 | timestruc_t ctime) |
| | 538 | { |
| | 539 | int rc, err; |
| | 540 | SHFLCREATEPARMS parms; |
| | 541 | SHFLSTRING *str; |
| | 542 | RTFSOBJINFO info; |
| | 543 | uint32_t bytes; |
| | 544 | int str_size; |
| | 545 | |
| | 546 | str = sfprov_string(path, &str_size); |
| | 547 | parms.Handle = 0; |
| | 548 | parms.Info.cbObject = 0; |
| | 549 | parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS |
| | 550 | | SHFL_CF_ACT_FAIL_IF_NEW |
| | 551 | | SHFL_CF_ACCESS_ATTR_WRITE; |
| | 552 | |
| | 553 | rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); |
| | 554 | |
| | 555 | if (RT_FAILURE(rc)) { |
| | 556 | cmn_err(CE_WARN, "sfprov_set_attr: vboxCallCreate(%s) failed rc=%d", |
| | 557 | path, rc); |
| | 558 | err = EINVAL; |
| | 559 | goto fail2; |
| | 560 | } |
| | 561 | if (parms.Result != SHFL_FILE_EXISTS) { |
| | 562 | err = ENOENT; |
| | 563 | goto fail1; |
| | 564 | } |
| | 565 | |
| | 566 | RT_ZERO(info); |
| | 567 | if (mask & AT_MODE) |
| | 568 | { |
| | 569 | #define mode_set(r) ((mode & (S_##r)) ? RTFS_UNIX_##r : 0) |
| | 570 | |
| | 571 | info.Attr.fMode = mode_set (ISUID); |
| | 572 | info.Attr.fMode |= mode_set (ISGID); |
| | 573 | info.Attr.fMode |= (mode & S_ISVTX) ? RTFS_UNIX_ISTXT : 0; |
| | 574 | info.Attr.fMode |= mode_set (IRUSR); |
| | 575 | info.Attr.fMode |= mode_set (IWUSR); |
| | 576 | info.Attr.fMode |= mode_set (IXUSR); |
| | 577 | info.Attr.fMode |= mode_set (IRGRP); |
| | 578 | info.Attr.fMode |= mode_set (IWGRP); |
| | 579 | info.Attr.fMode |= mode_set (IXGRP); |
| | 580 | info.Attr.fMode |= mode_set (IROTH); |
| | 581 | info.Attr.fMode |= mode_set (IWOTH); |
| | 582 | info.Attr.fMode |= mode_set (IXOTH); |
| | 583 | |
| | 584 | if (S_ISDIR(mode)) |
| | 585 | info.Attr.fMode |= RTFS_TYPE_DIRECTORY; |
| | 586 | else if (S_ISREG(mode)) |
| | 587 | info.Attr.fMode |= RTFS_TYPE_FILE; |
| | 588 | else if (S_ISFIFO(mode)) |
| | 589 | info.Attr.fMode |= RTFS_TYPE_FIFO; |
| | 590 | else if (S_ISCHR(mode)) |
| | 591 | info.Attr.fMode |= RTFS_TYPE_DEV_CHAR; |
| | 592 | else if (S_ISBLK(mode)) |
| | 593 | info.Attr.fMode |= RTFS_TYPE_DEV_BLOCK; |
| | 594 | else if (S_ISLNK(mode)) |
| | 595 | info.Attr.fMode |= RTFS_TYPE_SYMLINK; |
| | 596 | else if (S_ISSOCK(mode)) |
| | 597 | info.Attr.fMode |= RTFS_TYPE_SOCKET; |
| | 598 | else |
| | 599 | info.Attr.fMode |= RTFS_TYPE_FILE; |
| | 600 | } |
| | 601 | |
| | 602 | if (mask & AT_ATIME) |
| | 603 | sfprov_timespec_from_ftime(&info.AccessTime, atime); |
| | 604 | if (mask & AT_MTIME) |
| | 605 | sfprov_timespec_from_ftime(&info.ModificationTime, mtime); |
| | 606 | if (mask & AT_CTIME) |
| | 607 | sfprov_timespec_from_ftime(&info.ChangeTime, ctime); |
| | 608 | |
| | 609 | bytes = sizeof(info); |
| | 610 | rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle, |
| | 611 | (SHFL_INFO_SET | SHFL_INFO_FILE), &bytes, |
| | 612 | (SHFLDIRINFO *)&info); |
| | 613 | if (RT_FAILURE (rc)) { |
| | 614 | cmn_err(CE_WARN, "sfprov_set_attr: vboxCallFSInfo(%s, FILE) failed rc=%d", |
| | 615 | path, rc); |
| | 616 | err = RTErrConvertToErrno(rc); |
| | 617 | goto fail1; |
| | 618 | } |
| | 619 | |
| | 620 | err = 0; |
| | 621 | |
| | 622 | fail1: |
| | 623 | rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle); |
| | 624 | if (RT_FAILURE (rc)) |
| | 625 | { |
| | 626 | cmn_err(CE_WARN, "sfprov_set_attr: vboxCallClose(%s) failed rc=%d", |
| | 627 | path, rc); |
| | 628 | } |
| | 629 | fail2: |
| | 630 | kmem_free(str, str_size); |
| | 631 | return err; |
| | 632 | } |
| | 633 | |
| | 634 | int |
| | 635 | sfprov_set_size(sfp_mount_t *mnt, char *path, uint64_t size) |
| | 636 | { |
| | 637 | int rc, err; |
| | 638 | SHFLCREATEPARMS parms; |
| | 639 | SHFLSTRING *str; |
| | 640 | RTFSOBJINFO info; |
| | 641 | uint32_t bytes; |
| | 642 | int str_size; |
| | 643 | |
| | 644 | str = sfprov_string(path, &str_size); |
| | 645 | parms.Handle = 0; |
| | 646 | parms.Info.cbObject = 0; |
| | 647 | parms.CreateFlags = SHFL_CF_ACT_OPEN_IF_EXISTS |
| | 648 | | SHFL_CF_ACT_FAIL_IF_NEW |
| | 649 | | SHFL_CF_ACCESS_WRITE; |
| | 650 | |
| | 651 | rc = vboxCallCreate(&vbox_client, &mnt->map, str, &parms); |
| | 652 | |
| | 653 | if (RT_FAILURE(rc)) { |
| | 654 | cmn_err(CE_WARN, "sfprov_set_size: vboxCallCreate(%s) failed rc=%d", |
| | 655 | path, rc); |
| | 656 | err = EINVAL; |
| | 657 | goto fail2; |
| | 658 | } |
| | 659 | if (parms.Result != SHFL_FILE_EXISTS) { |
| | 660 | err = ENOENT; |
| | 661 | goto fail1; |
| | 662 | } |
| | 663 | |
| | 664 | RT_ZERO(info); |
| | 665 | info.cbObject = size; |
| | 666 | bytes = sizeof(info); |
| | 667 | rc = vboxCallFSInfo(&vbox_client, &mnt->map, parms.Handle, |
| | 668 | (SHFL_INFO_SET | SHFL_INFO_SIZE), &bytes, |
| | 669 | (SHFLDIRINFO *)&info); |
| | 670 | if (RT_FAILURE (rc)) { |
| | 671 | cmn_err(CE_WARN, "sfprov_set_size: vboxCallFSInfo(%s, SIZE) failed rc=%d", |
| | 672 | path, rc); |
| | 673 | err = RTErrConvertToErrno(rc); |
| | 674 | goto fail1; |
| | 675 | } |
| | 676 | |
| | 677 | err = 0; |
| | 678 | |
| | 679 | fail1: |
| | 680 | rc = vboxCallClose(&vbox_client, &mnt->map, parms.Handle); |
| | 681 | if (RT_FAILURE (rc)) |
| | 682 | { |
| | 683 | cmn_err(CE_WARN, "sfprov_set_size: vboxCallClose(%s) failed rc=%d", |
| | 684 | path, rc); |
| | 685 | } |
| | 686 | fail2: |
| | 687 | kmem_free(str, str_size); |
| | 688 | return err; |
| | 689 | } |
| | 690 | |