CFStringRef _FSCopyLocalizedNameForVolumeFormatAtNode(CFStringRef devnode) { CFStringRef formatName = NULL; char devnodename[MAXPATHLEN + 1]; char fsname[MAX_FSNAME]; int fssubtype = 0; /* convert CFStringRef devnode to CSTR */ if (true == CFStringGetCString(devnode, devnodename, MAXPATHLEN + 1, kCFStringEncodingUTF8)) { bool encrypted = false; encrypted = IsEncrypted(devnodename); /* get fsname and fssubtype */ memset(fsname, MAX_FSNAME, 0); if (getfstype(devnodename, fsname, &fssubtype) == true) { /* get unlocalized string */ CFStringRef fsType = CFStringCreateWithCString(NULL, fsname, kCFStringEncodingASCII); formatName = FSCopyFormatNameForFSType(fsType, fssubtype, true, encrypted); CFRelease(fsType); } } return formatName; }
int nametodisk(int *disk, long *offset, long *length) { int err, fstype, subdisk; struct part_desc pl[16]; char env[80], *envp, *pos1, *pos2, *cp; /* Decode E2CWD environment */ envp=getenv("E2CWD"); if (!envp) return E2E_NOCWD; strcpy(env,envp); /* We are going to modify it, so we make a copy */ pos1=strchr(env,':'); if (!pos1) return E2E_BADCWD; pos2=strchr(pos1+1,':'); *pos1 = 0; pos1++; for (cp=env; *cp; cp++) if (!isdigit(*cp)) return E2E_BADCWD; *disk = atoi(env); if (pos2) { *pos2 = 0; pos2++; } for (cp=pos1; *cp; cp++) if (!isdigit(*cp)) return E2E_BADCWD; subdisk = atoi(pos1)-1; if (pos2) { for (cp=pos2; *cp; cp++) if (!isdigit(*cp)) return E2E_BADCWD; cwdino = atoi(pos2); } else cwdino = EXT2_ROOT_INO; /* Check that disk contains an ext2 file system */ if (!(*disk & 0x80)) { /* Floppy disk */ *offset = 0; *length = 1440*2; /* TBD */ fstype=getfstype(*disk, 0, 0); if (fstype<0) return -fstype; if (fstype!=EXT2FS) return E2E_BADFS; return 0; } err=get_part(*disk, pl); if (err) return err; if (pl[subdisk].is_extended) return E2E_BADFS; fstype=getfstype(*disk, pl[subdisk].parttype, pl[subdisk].start); if (fstype<0) return -fstype; if (fstype!=EXT2FS) return E2E_BADFS; *offset = pl[subdisk].start; *length = pl[subdisk].length; return 0; }
int loadrootmodules(void) { struct vfssw *vsw; char *this; char *name; int err; /* ONC_PLUS EXTRACT END */ int i, proplen; extern char *impl_module_list[]; extern char *platform_module_list[]; /* Make sure that the PROM's devinfo tree has been created */ ASSERT(ddi_root_node()); BMDPRINTF(("loadrootmodules: fstype %s\n", rootfs.bo_fstype)); BMDPRINTF(("loadrootmodules: name %s\n", rootfs.bo_name)); BMDPRINTF(("loadrootmodules: flags 0x%x\n", rootfs.bo_flags)); /* * zzz We need to honor what's in rootfs if it's not null. * non-null means use what's there. This way we can * change rootfs with /etc/system AND with tunetool. */ if (root_is_svm) { /* user replaced rootdev, record obp_bootpath */ obp_bootpath[0] = '\0'; (void) getphysdev("root", obp_bootpath, BO_MAXOBJNAME); BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); } else { /* * Get the root fstype and root device path from boot. */ rootfs.bo_fstype[0] = '\0'; rootfs.bo_name[0] = '\0'; } /* * This lookup will result in modloadonly-ing the root * filesystem module - it gets _init-ed in rootconf() */ if ((vsw = getfstype("root", rootfs.bo_fstype, BO_MAXFSNAME)) == NULL) return (ENXIO); /* in case we have no file system types */ (void) strcpy(rootfs.bo_fstype, vsw->vsw_name); vfs_unrefvfssw(vsw); /* * Load the favored drivers of the implementation. * e.g. 'sbus' and possibly 'zs' (even). * * Called whilst boot is still loaded (because boot does * the i/o for us), and DDI services are unavailable. */ BMDPRINTF(("loadrootmodules: impl_module_list\n")); for (i = 0; (this = impl_module_list[i]) != NULL; i++) { if ((err = load_boot_driver(this)) != 0) { cmn_err(CE_WARN, "Cannot load drv/%s", this); return (err); /* NOTREACHED */ } } /* * Now load the platform modules (if any) */ BMDPRINTF(("loadrootmodules: platform_module_list\n")); for (i = 0; (this = platform_module_list[i]) != NULL; i++) { if ((err = load_boot_platform_modules(this)) != 0) { cmn_err(CE_WARN, "Cannot load drv/%s", this); return (err); /* NOTREACHED */ } } loop: (void) getphysdev("root", rootfs.bo_name, BO_MAXOBJNAME); /* * Given a physical pathname, load the correct set of driver * modules into memory, including all possible parents. * * NB: The code sets the variable 'name' for error reporting. */ err = 0; BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); if (root_is_svm == 0) { BMDPRINTF(("loadrootmodules: rootfs %s\n", rootfs.bo_name)); name = rootfs.bo_name; err = load_bootpath_drivers(rootfs.bo_name); } /* * Load driver modules in obp_bootpath, this is always * required for mountroot to succeed. obp_bootpath is * is set if rootdev is set via /etc/system, which is * the case if booting of a SVM/VxVM mirror. */ if ((err == 0) && obp_bootpath[0] != '\0') { BMDPRINTF(("loadrootmodules: obp_bootpath %s\n", obp_bootpath)); name = obp_bootpath; err = load_bootpath_drivers(obp_bootpath); } if (err != 0) { cmn_err(CE_CONT, "Cannot load drivers for %s\n", name); goto out; /* NOTREACHED */ } /* * Check to see if the booter performed DHCP configuration * ("bootp-response" boot property exists). If so, then before * bootops disappears we need to save the value of this property * such that the userland dhcpagent can adopt the DHCP management * of our primary network interface. */ proplen = BOP_GETPROPLEN(bootops, "bootp-response"); if (proplen > 0) { dhcack = kmem_zalloc(proplen, KM_SLEEP); if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) { cmn_err(CE_WARN, "BOP_GETPROP of " "\"bootp-response\" failed\n"); kmem_free(dhcack, dhcacklen); dhcack = NULL; goto out; } dhcacklen = proplen; /* * Fetch the "netdev-path" boot property (if it exists), and * stash it for later use by sysinfo(SI_DHCP_CACHE, ...). */ proplen = BOP_GETPROPLEN(bootops, "netdev-path"); if (proplen > 0) { netdev_path = kmem_zalloc(proplen, KM_SLEEP); if (BOP_GETPROP(bootops, "netdev-path", (uchar_t *)netdev_path) == -1) { cmn_err(CE_WARN, "BOP_GETPROP of " "\"netdev-path\" failed\n"); kmem_free(netdev_path, proplen); goto out; } } } /* * Preload (load-only, no init) all modules which * were added to the /etc/system file with the * FORCELOAD keyword. */ BMDPRINTF(("loadrootmodules: preload_module\n")); (void) mod_sysctl_type(MOD_FORCELOAD, preload_module, NULL); /* ONC_PLUS EXTRACT START */ /* * If we booted otw then load in the plumbing * routine now while we still can. If we didn't * boot otw then we will load strplumb in main(). * * NFS is actually a set of modules, the core routines, * a diskless helper module, rpcmod, and the tli interface. Load * them now while we still can. * * Because we glomb all versions of nfs into a single module * we check based on the initial string "nfs". * * XXX: A better test for this is to see if device_type * XXX: from the PROM is "network". */ if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) { ++netboot; if ((err = modload("misc", "tlimod")) < 0) { cmn_err(CE_CONT, "Cannot load misc/tlimod\n"); goto out; /* NOTREACHED */ } if ((err = modload("strmod", "rpcmod")) < 0) { cmn_err(CE_CONT, "Cannot load strmod/rpcmod\n"); goto out; /* NOTREACHED */ } if ((err = modload("misc", "nfs_dlboot")) < 0) { cmn_err(CE_CONT, "Cannot load misc/nfs_dlboot\n"); goto out; /* NOTREACHED */ } if ((err = modload("mac", "mac_ether")) < 0) { cmn_err(CE_CONT, "Cannot load mac/mac_ether\n"); goto out; /* NOTREACHED */ } if ((err = modload("misc", "strplumb")) < 0) { cmn_err(CE_CONT, "Cannot load misc/strplumb\n"); goto out; /* NOTREACHED */ } if ((err = strplumb_load()) < 0) { goto out; /* NOTREACHED */ } } /* * Preload modules needed for booting as a cluster. */ err = clboot_loadrootmodules(); out: if (err != 0 && (boothowto & RB_ASKNAME)) goto loop; return (err); }
/* * Add the file or dir hierarchy named by 'path' to the archive */ static void write_hierarchy(struct bsdtar *bsdtar, struct archive *a, const char *path) { struct archive_entry *entry = NULL, *spare_entry = NULL; struct tree *tree; char symlink_mode = bsdtar->symlink_mode; dev_t first_dev = 0; int dev_recorded = 0; int tree_ret; dev_t last_dev = 0; char * fstype; tree = tree_open(path); if (!tree) { bsdtar_warnc(bsdtar, errno, "%s: Cannot open", path); bsdtar->return_value = 1; return; } while ((tree_ret = tree_next(tree))) { int r; const char *name = tree_current_path(tree); const struct stat *st = NULL; /* info to use for this entry */ const struct stat *lst = NULL; /* lstat() information */ int descend; if (truncate_archive(bsdtar)) break; if (checkpoint_archive(bsdtar, 0)) exit(1); disk_pause(bsdtar); if (network_select(0)) exit(1); if (tree_ret == TREE_ERROR_FATAL) bsdtar_errc(bsdtar, 1, tree_errno(tree), "%s: Unable to continue traversing directory tree", name); if (tree_ret == TREE_ERROR_DIR) { bsdtar_warnc(bsdtar, errno, "%s: Couldn't visit directory", name); bsdtar->return_value = 1; } if (tree_ret != TREE_REGULAR) continue; /* * If this file/dir is excluded by a filename * pattern, skip it. */ if (excluded(bsdtar, name)) continue; /* * Get lstat() info from the tree library. */ lst = tree_current_lstat(tree); if (lst == NULL) { /* Couldn't lstat(); must not exist. */ bsdtar_warnc(bsdtar, errno, "%s: Cannot stat", name); /* Return error if files disappear during traverse. */ bsdtar->return_value = 1; continue; } /* * Distinguish 'L'/'P'/'H' symlink following. */ switch(symlink_mode) { case 'H': /* 'H': After the first item, rest like 'P'. */ symlink_mode = 'P'; /* 'H': First item (from command line) like 'L'. */ /* FALLTHROUGH */ case 'L': /* 'L': Do descend through a symlink to dir. */ descend = tree_current_is_dir(tree); /* 'L': Follow symlinks to files. */ archive_read_disk_set_symlink_logical(bsdtar->diskreader); /* 'L': Archive symlinks as targets, if we can. */ st = tree_current_stat(tree); if (st != NULL) break; /* If stat fails, we have a broken symlink; * in that case, don't follow the link. */ /* FALLTHROUGH */ default: /* 'P': Don't descend through a symlink to dir. */ descend = tree_current_is_physical_dir(tree); /* 'P': Don't follow symlinks to files. */ archive_read_disk_set_symlink_physical(bsdtar->diskreader); /* 'P': Archive symlinks as symlinks. */ st = lst; break; } if (bsdtar->option_no_subdirs) descend = 0; /* * If user has asked us not to cross mount points, * then don't descend into a dir on a different * device. */ if (!dev_recorded) { last_dev = first_dev = lst->st_dev; dev_recorded = 1; } if (bsdtar->option_dont_traverse_mounts) { if (lst->st_dev != first_dev) descend = 0; } /* * If the user did not specify --insane-filesystems, do not * cross into a new filesystem which is known to be synthetic. * Note that we will archive synthetic filesystems if we are * explicitly told to do so. */ if ((bsdtar->option_insane_filesystems == 0) && (descend != 0) && (lst->st_dev != last_dev)) { fstype = getfstype(tree_current_access_path(tree)); if (fstype == NULL) bsdtar_errc(bsdtar, 1, errno, "%s: Error getting filesystem type", name); if (getfstype_issynthetic(fstype)) { if (!bsdtar->option_quiet) bsdtar_warnc(bsdtar, 0, "Not descending into filesystem of type %s: %s", fstype, name); descend = 0; } else { /* This device is ok to archive. */ last_dev = lst->st_dev; } free(fstype); } /* * In -u mode, check that the file is newer than what's * already in the archive; in all modes, obey --newerXXX flags. */ if (!new_enough(bsdtar, name, st)) { if (!descend) continue; if (bsdtar->option_interactive && !yes("add '%s'", name)) continue; tree_descend(tree); continue; } archive_entry_free(entry); entry = archive_entry_new(); archive_entry_set_pathname(entry, name); archive_entry_copy_sourcepath(entry, tree_current_access_path(tree)); /* Populate the archive_entry with metadata from the disk. */ /* XXX TODO: Arrange to open a regular file before * calling this so we can pass in an fd and shorten * the race to query metadata. The linkify dance * makes this more complex than it might sound. */ r = archive_read_disk_entry_from_file(bsdtar->diskreader, entry, -1, st); if (r != ARCHIVE_OK) bsdtar_warnc(bsdtar, archive_errno(bsdtar->diskreader), "%s", archive_error_string(bsdtar->diskreader)); if (r < ARCHIVE_WARN) continue; /* XXX TODO: Just use flag data from entry; avoid the * duplicate check here. */ /* * If this file/dir is flagged "nodump" and we're * honoring such flags, skip this file/dir. */ #if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) /* BSD systems store flags in struct stat */ if (bsdtar->option_honor_nodump && (lst->st_flags & UF_NODUMP)) continue; #endif #if defined(EXT2_NODUMP_FL) /* Linux uses ioctl to read flags. */ if (bsdtar->option_honor_nodump) { unsigned long fflags, dummy; archive_entry_fflags(entry, &fflags, &dummy); if (fflags & EXT2_NODUMP_FL) continue; } #endif /* * Don't back up the cache directory or any files inside it. */ if ((lst->st_ino == bsdtar->cachedir_ino) && (lst->st_dev == bsdtar->cachedir_dev)) { if (!bsdtar->option_quiet) bsdtar_warnc(bsdtar, 0, "Not adding cache directory to archive: %s", name); continue; } /* * If the user vetoes this file/directory, skip it. * We want this to be fairly late; if some other * check would veto this file, we shouldn't bother * the user with it. */ if (bsdtar->option_interactive && !yes("add '%s'", name)) continue; /* Note: if user vetoes, we won't descend. */ if (descend) tree_descend(tree); /* * Rewrite the pathname to be archived. If rewrite * fails, skip the entry. */ if (edit_pathname(bsdtar, entry)) continue; /* * If this is a socket, skip the entry: POSIX requires that * pax(1) emit a "diagnostic message" (i.e., warning) that * sockets cannot be archived, but this can make backups of * running systems very noisy. */ if (S_ISSOCK(st->st_mode)) continue; /* Display entry as we process it. * This format is required by SUSv2. */ if (bsdtar->verbose) safe_fprintf(stderr, "a %s", archive_entry_pathname(entry)); /* * If the user hasn't specifically asked to have the access * time stored, zero it. At the moment this usually only * matters for files which have flags set, since the "posix * restricted" format doesn't store access times for most * other files. */ if (bsdtar->option_store_atime == 0) archive_entry_set_atime(entry, 0, 0); /* Non-regular files get archived with zero size. */ if (!S_ISREG(st->st_mode)) archive_entry_set_size(entry, 0); /* Record what we're doing, for SIGINFO / SIGUSR1. */ siginfo_setinfo(bsdtar, "adding", archive_entry_pathname(entry), archive_entry_size(entry)); archive_entry_linkify(bsdtar->resolver, &entry, &spare_entry); /* Handle SIGINFO / SIGUSR1 request if one was made. */ siginfo_printinfo(bsdtar, 0); while (entry != NULL) { write_entry_backend(bsdtar, a, entry, st, tree_current_realpath(tree)); archive_entry_free(entry); entry = spare_entry; spare_entry = NULL; } if (bsdtar->verbose) fprintf(stderr, "\n"); } archive_entry_free(entry); if (tree_close(tree)) bsdtar_errc(bsdtar, 1, 0, "Error traversing directory tree"); }