package cmd import ( "sort" "os/exec" "strings" ) /***************************************************************************** * * Command execution * *****************************************************************************/ func executeCommand(cmdline string) (string, error) { var cmd []string var out []byte var err error if gUseSudo { cmd = append(cmd, "sudo") } cs := strings.Split(cmdline, " ") cmd = append(cmd, cs...) if len (cmd) > 1 { out, err = exec.Command(cmd[0], cmd[1:]...).Output() } else { out, err = exec.Command(cmd[0]).Output() } return string(out), err } func executeCommandInJail(jail *Jail, cmdline string) (string, error) { var cmd []string if gUseSudo { cmd = append(cmd, "sudo") } cmd = append(cmd, "setfib") if len(jail.Config.Exec_fib) > 0 { cmd = append(cmd, jail.Config.Exec_fib) } else { cmd = append(cmd, "0") } cmd = append(cmd, "jexec", jail.InternalName) cs := strings.Split(cmdline, " ") cmd = append(cmd, cs...) out, err := exec.Command(cmd[0], cmd[1:]...).Output() return string(out), err } /***************************************************************************** * * Sorting jails * *****************************************************************************/ // already defined in cmd/struct.go //type lessFunc func(j1 *Jail, j2 *Jail) bool func initSortStruct() JailSort { jcs := JailConfigSort{ Allow_chflagsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_chflags < j2.Config.Allow_chflags }, Allow_chflagsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_chflags > j2.Config.Allow_chflags }, Allow_mlockInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mlock < j2.Config.Allow_mlock }, Allow_mlockDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mlock > j2.Config.Allow_mlock }, Allow_mountInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount < j2.Config.Allow_mount }, Allow_mountDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount > j2.Config.Allow_mount }, Allow_mount_devfsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_devfs < j2.Config.Allow_mount_devfs }, Allow_mount_devfsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_devfs > j2.Config.Allow_mount_devfs }, Allow_mount_fusefsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_fusefs < j2.Config.Allow_mount_fusefs }, Allow_mount_fusefsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_fusefs > j2.Config.Allow_mount_fusefs }, Allow_mount_nullfsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_nullfs < j2.Config.Allow_mount_nullfs }, Allow_mount_nullfsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_nullfs > j2.Config.Allow_mount_nullfs }, Allow_mount_procfsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_procfs < j2.Config.Allow_mount_procfs }, Allow_mount_procfsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_procfs > j2.Config.Allow_mount_procfs }, Allow_mount_tmpfsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_tmpfs < j2.Config.Allow_mount_tmpfs }, Allow_mount_tmpfsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_tmpfs > j2.Config.Allow_mount_tmpfs }, Allow_mount_zfsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_zfs < j2.Config.Allow_mount_zfs }, Allow_mount_zfsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_mount_zfs > j2.Config.Allow_mount_zfs }, Allow_quotasInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_quotas < j2.Config.Allow_quotas }, Allow_quotasDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_quotas > j2.Config.Allow_quotas }, Allow_raw_socketsInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_raw_sockets < j2.Config.Allow_raw_sockets }, Allow_raw_socketsDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_raw_sockets > j2.Config.Allow_raw_sockets }, Allow_set_hostnameInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_set_hostname < j2.Config.Allow_set_hostname }, Allow_set_hostnameDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_set_hostname > j2.Config.Allow_set_hostname }, Allow_socket_afInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_socket_af < j2.Config.Allow_socket_af }, Allow_socket_afDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_socket_af > j2.Config.Allow_socket_af }, Allow_sysvipcInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_sysvipc < j2.Config.Allow_sysvipc }, Allow_sysvipcDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_sysvipc > j2.Config.Allow_sysvipc }, Allow_tunInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_tun < j2.Config.Allow_tun }, Allow_tunDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_tun > j2.Config.Allow_tun }, Allow_vmmInc: func(j1, j2 *Jail) bool { return j1.Config.Allow_vmm < j2.Config.Allow_vmm }, Allow_vmmDec: func(j1, j2 *Jail) bool { return j1.Config.Allow_vmm > j2.Config.Allow_vmm }, Assign_localhostInc: func(j1, j2 *Jail) bool { return j1.Config.Assign_localhost < j2.Config.Assign_localhost }, Assign_localhostDec: func(j1, j2 *Jail) bool { return j1.Config.Assign_localhost > j2.Config.Assign_localhost }, AvailableInc: func(j1, j2 *Jail) bool { return j1.Config.Available < j2.Config.Available }, AvailableDec: func(j1, j2 *Jail) bool { return j1.Config.Available > j2.Config.Available }, BasejailInc: func(j1, j2 *Jail) bool { return j1.Config.Basejail < j2.Config.Basejail }, BasejailDec: func(j1, j2 *Jail) bool { return j1.Config.Basejail > j2.Config.Basejail }, BootInc: func(j1, j2 *Jail) bool { return j1.Config.Boot < j2.Config.Boot }, BootDec: func(j1, j2 *Jail) bool { return j1.Config.Boot > j2.Config.Boot }, BpfInc: func(j1, j2 *Jail) bool { return j1.Config.Bpf < j2.Config.Bpf }, BpfDec: func(j1, j2 *Jail) bool { return j1.Config.Bpf > j2.Config.Bpf }, Children_maxInc: func(j1, j2 *Jail) bool { return j1.Config.Children_max < j2.Config.Children_max }, Children_maxDec: func(j1, j2 *Jail) bool { return j1.Config.Children_max > j2.Config.Children_max }, Cloned_releaseInc: func(j1, j2 *Jail) bool { return j1.Config.Cloned_release < j2.Config.Cloned_release }, Cloned_releaseDec: func(j1, j2 *Jail) bool { return j1.Config.Cloned_release > j2.Config.Cloned_release }, CommentInc: func(j1, j2 *Jail) bool { return j1.Config.Comment < j2.Config.Comment }, CommentDec: func(j1, j2 *Jail) bool { return j1.Config.Comment > j2.Config.Comment }, CompressionInc: func(j1, j2 *Jail) bool { return j1.Config.Compression < j2.Config.Compression }, CompressionDec: func(j1, j2 *Jail) bool { return j1.Config.Compression > j2.Config.Compression }, CompressratioInc: func(j1, j2 *Jail) bool { return j1.Config.Compressratio < j2.Config.Compressratio }, CompressratioDec: func(j1, j2 *Jail) bool { return j1.Config.Compressratio > j2.Config.Compressratio }, Config_versionInc: func(j1, j2 *Jail) bool { return j1.Config.Config_version < j2.Config.Config_version }, Config_versionDec: func(j1, j2 *Jail) bool { return j1.Config.Config_version > j2.Config.Config_version }, CoredumpsizeInc: func(j1, j2 *Jail) bool { return j1.Config.Coredumpsize < j2.Config.Coredumpsize }, CoredumpsizeDec: func(j1, j2 *Jail) bool { return j1.Config.Coredumpsize > j2.Config.Coredumpsize }, CountInc: func(j1, j2 *Jail) bool { return j1.Config.Count < j2.Config.Count }, CountDec: func(j1, j2 *Jail) bool { return j1.Config.Count > j2.Config.Count }, CpusetInc: func(j1, j2 *Jail) bool { return j1.Config.Cpuset < j2.Config.Cpuset }, CpusetDec: func(j1, j2 *Jail) bool { return j1.Config.Cpuset > j2.Config.Cpuset }, CputimeInc: func(j1, j2 *Jail) bool { return j1.Config.Cputime < j2.Config.Cputime }, CputimeDec: func(j1, j2 *Jail) bool { return j1.Config.Cputime > j2.Config.Cputime }, DatasizeInc: func(j1, j2 *Jail) bool { return j1.Config.Datasize < j2.Config.Datasize }, DatasizeDec: func(j1, j2 *Jail) bool { return j1.Config.Datasize > j2.Config.Datasize }, DedupInc: func(j1, j2 *Jail) bool { return j1.Config.Dedup < j2.Config.Dedup }, DedupDec: func(j1, j2 *Jail) bool { return j1.Config.Dedup > j2.Config.Dedup }, DefaultrouterInc: func(j1, j2 *Jail) bool { return j1.Config.Defaultrouter < j2.Config.Defaultrouter }, DefaultrouterDec: func(j1, j2 *Jail) bool { return j1.Config.Defaultrouter > j2.Config.Defaultrouter }, Defaultrouter6Inc: func(j1, j2 *Jail) bool { return j1.Config.Defaultrouter6 < j2.Config.Defaultrouter6 }, Defaultrouter6Dec: func(j1, j2 *Jail) bool { return j1.Config.Defaultrouter6 > j2.Config.Defaultrouter6 }, DependsInc: func(j1, j2 *Jail) bool { return j1.Config.Depends < j2.Config.Depends }, DependsDec: func(j1, j2 *Jail) bool { return j1.Config.Depends > j2.Config.Depends }, Devfs_rulesetInc: func(j1, j2 *Jail) bool { return j1.Config.Devfs_ruleset < j2.Config.Devfs_ruleset }, Devfs_rulesetDec: func(j1, j2 *Jail) bool { return j1.Config.Devfs_ruleset > j2.Config.Devfs_ruleset }, DhcpInc: func(j1, j2 *Jail) bool { return j1.Config.Dhcp < j2.Config.Dhcp }, DhcpDec: func(j1, j2 *Jail) bool { return j1.Config.Dhcp > j2.Config.Dhcp }, Enforce_statfsInc: func(j1, j2 *Jail) bool { return j1.Config.Enforce_statfs < j2.Config.Enforce_statfs }, Enforce_statfsDec: func(j1, j2 *Jail) bool { return j1.Config.Enforce_statfs > j2.Config.Enforce_statfs }, Exec_cleanInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_clean < j2.Config.Exec_clean }, Exec_cleanDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_clean > j2.Config.Exec_clean }, Exec_createdInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_created < j2.Config.Exec_created }, Exec_createdDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_created > j2.Config.Exec_created }, Exec_fibInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_fib < j2.Config.Exec_fib }, Exec_fibDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_fib > j2.Config.Exec_fib }, Exec_jail_userInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_jail_user < j2.Config.Exec_jail_user }, Exec_jail_userDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_jail_user > j2.Config.Exec_jail_user }, Exec_poststartInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_poststart < j2.Config.Exec_poststart }, Exec_poststartDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_poststart > j2.Config.Exec_poststart }, Exec_poststopInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_poststop < j2.Config.Exec_poststop }, Exec_poststopDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_poststop > j2.Config.Exec_poststop }, Exec_prestartInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_prestart < j2.Config.Exec_prestart }, Exec_prestartDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_prestart > j2.Config.Exec_prestart }, Exec_prestopInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_prestop < j2.Config.Exec_prestop }, Exec_prestopDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_prestop > j2.Config.Exec_prestop }, Exec_startInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_start < j2.Config.Exec_start }, Exec_startDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_start > j2.Config.Exec_start }, Exec_stopInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_stop < j2.Config.Exec_stop }, Exec_stopDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_stop > j2.Config.Exec_stop }, Exec_system_jail_userInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_system_jail_user < j2.Config.Exec_system_jail_user }, Exec_system_jail_userDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_system_jail_user > j2.Config.Exec_system_jail_user }, Exec_system_userInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_system_user < j2.Config.Exec_system_user }, Exec_system_userDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_system_user > j2.Config.Exec_system_user }, Exec_timeoutInc: func(j1, j2 *Jail) bool { return j1.Config.Exec_timeout < j2.Config.Exec_timeout }, Exec_timeoutDec: func(j1, j2 *Jail) bool { return j1.Config.Exec_timeout > j2.Config.Exec_timeout }, Host_domainnameInc: func(j1, j2 *Jail) bool { return j1.Config.Host_domainname < j2.Config.Host_domainname }, Host_domainnameDec: func(j1, j2 *Jail) bool { return j1.Config.Host_domainname > j2.Config.Host_domainname }, Host_hostnameInc: func(j1, j2 *Jail) bool { return j1.Config.Host_hostname < j2.Config.Host_hostname }, Host_hostnameDec: func(j1, j2 *Jail) bool { return j1.Config.Host_hostname > j2.Config.Host_hostname }, Host_hostuuidInc: func(j1, j2 *Jail) bool { return j1.Config.Host_hostuuid < j2.Config.Host_hostuuid }, Host_hostuuidDec: func(j1, j2 *Jail) bool { return j1.Config.Host_hostuuid > j2.Config.Host_hostuuid }, Host_timeInc: func(j1, j2 *Jail) bool { return j1.Config.Host_time < j2.Config.Host_time }, Host_timeDec: func(j1, j2 *Jail) bool { return j1.Config.Host_time > j2.Config.Host_time }, HostidInc: func(j1, j2 *Jail) bool { return j1.Config.Hostid < j2.Config.Hostid }, HostidDec: func(j1, j2 *Jail) bool { return j1.Config.Hostid > j2.Config.Hostid }, Hostid_strict_checkInc: func(j1, j2 *Jail) bool { return j1.Config.Hostid_strict_check < j2.Config.Hostid_strict_check }, Hostid_strict_checkDec: func(j1, j2 *Jail) bool { return j1.Config.Hostid_strict_check > j2.Config.Hostid_strict_check }, InterfacesInc: func(j1, j2 *Jail) bool { return j1.Config.Interfaces < j2.Config.Interfaces }, InterfacesDec: func(j1, j2 *Jail) bool { return j1.Config.Interfaces > j2.Config.Interfaces }, Ip_hostnameInc: func(j1, j2 *Jail) bool { return j1.Config.Ip_hostname < j2.Config.Ip_hostname }, Ip_hostnameDec: func(j1, j2 *Jail) bool { return j1.Config.Ip_hostname > j2.Config.Ip_hostname }, Ip4Inc: func(j1, j2 *Jail) bool { return j1.Config.Ip4 < j2.Config.Ip4 }, Ip4Dec: func(j1, j2 *Jail) bool { return j1.Config.Ip4 > j2.Config.Ip4 }, Ip4_addrInc: func(j1, j2 *Jail) bool { return j1.Config.Ip4_addr < j2.Config.Ip4_addr }, Ip4_addrDec: func(j1, j2 *Jail) bool { return j1.Config.Ip4_addr > j2.Config.Ip4_addr }, Ip4_saddrselInc: func(j1, j2 *Jail) bool { return j1.Config.Ip4_saddrsel < j2.Config.Ip4_saddrsel }, Ip4_saddrselDec: func(j1, j2 *Jail) bool { return j1.Config.Ip4_saddrsel > j2.Config.Ip4_saddrsel }, Ip6Inc: func(j1, j2 *Jail) bool { return j1.Config.Ip6 < j2.Config.Ip6 }, Ip6Dec: func(j1, j2 *Jail) bool { return j1.Config.Ip6 > j2.Config.Ip6 }, Ip6_addrInc: func(j1, j2 *Jail) bool { return j1.Config.Ip6_addr < j2.Config.Ip6_addr }, Ip6_addrDec: func(j1, j2 *Jail) bool { return j1.Config.Ip6_addr > j2.Config.Ip6_addr }, Ip6_saddrselInc: func(j1, j2 *Jail) bool { return j1.Config.Ip6_saddrsel < j2.Config.Ip6_saddrsel }, Ip6_saddrselDec: func(j1, j2 *Jail) bool { return j1.Config.Ip6_saddrsel > j2.Config.Ip6_saddrsel }, Jail_zfsInc: func(j1, j2 *Jail) bool { return j1.Config.Jail_zfs < j2.Config.Jail_zfs }, Jail_zfsDec: func(j1, j2 *Jail) bool { return j1.Config.Jail_zfs > j2.Config.Jail_zfs }, Jail_zfs_datasetInc: func(j1, j2 *Jail) bool { return j1.Config.Jail_zfs_dataset < j2.Config.Jail_zfs_dataset }, Jail_zfs_datasetDec: func(j1, j2 *Jail) bool { return j1.Config.Jail_zfs_dataset > j2.Config.Jail_zfs_dataset }, Jail_zfs_mountpointInc: func(j1, j2 *Jail) bool { return j1.Config.Jail_zfs_mountpoint < j2.Config.Jail_zfs_mountpoint }, Jail_zfs_mountpointDec: func(j1, j2 *Jail) bool { return j1.Config.Jail_zfs_mountpoint > j2.Config.Jail_zfs_mountpoint }, JailtypeInc: func(j1, j2 *Jail) bool { return j1.Config.Jailtype < j2.Config.Jailtype }, JailtypeDec: func(j1, j2 *Jail) bool { return j1.Config.Jailtype > j2.Config.Jailtype }, Last_startedInc: func(j1, j2 *Jail) bool { return j1.Config.Last_started < j2.Config.Last_started }, Last_startedDec: func(j1, j2 *Jail) bool { return j1.Config.Last_started > j2.Config.Last_started }, Localhost_ipInc: func(j1, j2 *Jail) bool { return j1.Config.Localhost_ip < j2.Config.Localhost_ip }, Localhost_ipDec: func(j1, j2 *Jail) bool { return j1.Config.Localhost_ip > j2.Config.Localhost_ip }, Login_flagsInc: func(j1, j2 *Jail) bool { return j1.Config.Login_flags < j2.Config.Login_flags }, Login_flagsDec: func(j1, j2 *Jail) bool { return j1.Config.Login_flags > j2.Config.Login_flags }, Mac_prefixInc: func(j1, j2 *Jail) bool { return j1.Config.Mac_prefix < j2.Config.Mac_prefix }, Mac_prefixDec: func(j1, j2 *Jail) bool { return j1.Config.Mac_prefix > j2.Config.Mac_prefix }, MaxprocInc: func(j1, j2 *Jail) bool { return j1.Config.Maxproc < j2.Config.Maxproc }, MaxprocDec: func(j1, j2 *Jail) bool { return j1.Config.Maxproc > j2.Config.Maxproc }, MemorylockedInc: func(j1, j2 *Jail) bool { return j1.Config.Memorylocked < j2.Config.Memorylocked }, MemorylockedDec: func(j1, j2 *Jail) bool { return j1.Config.Memorylocked > j2.Config.Memorylocked }, MemoryuseInc: func(j1, j2 *Jail) bool { return j1.Config.Memoryuse < j2.Config.Memoryuse }, MemoryuseDec: func(j1, j2 *Jail) bool { return j1.Config.Memoryuse > j2.Config.Memoryuse }, Min_dyn_devfs_rulesetInc: func(j1, j2 *Jail) bool { return j1.Config.Min_dyn_devfs_ruleset < j2.Config.Min_dyn_devfs_ruleset }, Min_dyn_devfs_rulesetDec: func(j1, j2 *Jail) bool { return j1.Config.Min_dyn_devfs_ruleset > j2.Config.Min_dyn_devfs_ruleset }, Mount_devfsInc: func(j1, j2 *Jail) bool { return j1.Config.Mount_devfs < j2.Config.Mount_devfs }, Mount_devfsDec: func(j1, j2 *Jail) bool { return j1.Config.Mount_devfs > j2.Config.Mount_devfs }, Mount_fdescfsInc: func(j1, j2 *Jail) bool { return j1.Config.Mount_fdescfs < j2.Config.Mount_fdescfs }, Mount_fdescfsDec: func(j1, j2 *Jail) bool { return j1.Config.Mount_fdescfs > j2.Config.Mount_fdescfs }, Mount_linprocfsInc: func(j1, j2 *Jail) bool { return j1.Config.Mount_linprocfs < j2.Config.Mount_linprocfs }, Mount_linprocfsDec: func(j1, j2 *Jail) bool { return j1.Config.Mount_linprocfs > j2.Config.Mount_linprocfs }, Mount_procfsInc: func(j1, j2 *Jail) bool { return j1.Config.Mount_procfs < j2.Config.Mount_procfs }, Mount_procfsDec: func(j1, j2 *Jail) bool { return j1.Config.Mount_procfs > j2.Config.Mount_procfs }, MountpointInc: func(j1, j2 *Jail) bool { return j1.Config.Mountpoint < j2.Config.Mountpoint }, MountpointDec: func(j1, j2 *Jail) bool { return j1.Config.Mountpoint > j2.Config.Mountpoint }, MsgqqueuedInc: func(j1, j2 *Jail) bool { return j1.Config.Msgqqueued < j2.Config.Msgqqueued }, MsgqqueuedDec: func(j1, j2 *Jail) bool { return j1.Config.Msgqqueued > j2.Config.Msgqqueued }, MsgqsizeInc: func(j1, j2 *Jail) bool { return j1.Config.Msgqsize < j2.Config.Msgqsize }, MsgqsizeDec: func(j1, j2 *Jail) bool { return j1.Config.Msgqsize > j2.Config.Msgqsize }, NatInc: func(j1, j2 *Jail) bool { return j1.Config.Nat < j2.Config.Nat }, NatDec: func(j1, j2 *Jail) bool { return j1.Config.Nat > j2.Config.Nat }, Nat_backendInc: func(j1, j2 *Jail) bool { return j1.Config.Nat_backend < j2.Config.Nat_backend }, Nat_backendDec: func(j1, j2 *Jail) bool { return j1.Config.Nat_backend > j2.Config.Nat_backend }, Nat_forwardsInc: func(j1, j2 *Jail) bool { return j1.Config.Nat_forwards < j2.Config.Nat_forwards }, Nat_forwardsDec: func(j1, j2 *Jail) bool { return j1.Config.Nat_forwards > j2.Config.Nat_forwards }, Nat_interfaceInc: func(j1, j2 *Jail) bool { return j1.Config.Nat_interface < j2.Config.Nat_interface }, Nat_interfaceDec: func(j1, j2 *Jail) bool { return j1.Config.Nat_interface > j2.Config.Nat_interface }, Nat_prefixInc: func(j1, j2 *Jail) bool { return j1.Config.Nat_prefix < j2.Config.Nat_prefix }, Nat_prefixDec: func(j1, j2 *Jail) bool { return j1.Config.Nat_prefix > j2.Config.Nat_prefix }, NmsgqInc: func(j1, j2 *Jail) bool { return j1.Config.Nmsgq < j2.Config.Nmsgq }, NmsgqDec: func(j1, j2 *Jail) bool { return j1.Config.Nmsgq > j2.Config.Nmsgq }, NotesInc: func(j1, j2 *Jail) bool { return j1.Config.Notes < j2.Config.Notes }, NotesDec: func(j1, j2 *Jail) bool { return j1.Config.Notes > j2.Config.Notes }, NsemInc: func(j1, j2 *Jail) bool { return j1.Config.Nsem < j2.Config.Nsem }, NsemDec: func(j1, j2 *Jail) bool { return j1.Config.Nsem > j2.Config.Nsem }, NsemopInc: func(j1, j2 *Jail) bool { return j1.Config.Nsemop < j2.Config.Nsemop }, NsemopDec: func(j1, j2 *Jail) bool { return j1.Config.Nsemop > j2.Config.Nsemop }, NshmInc: func(j1, j2 *Jail) bool { return j1.Config.Nshm < j2.Config.Nshm }, NshmDec: func(j1, j2 *Jail) bool { return j1.Config.Nshm > j2.Config.Nshm }, NthrInc: func(j1, j2 *Jail) bool { return j1.Config.Nthr < j2.Config.Nthr }, NthrDec: func(j1, j2 *Jail) bool { return j1.Config.Nthr > j2.Config.Nthr }, OpenfilesInc: func(j1, j2 *Jail) bool { return j1.Config.Openfiles < j2.Config.Openfiles }, OpenfilesDec: func(j1, j2 *Jail) bool { return j1.Config.Openfiles > j2.Config.Openfiles }, OriginInc: func(j1, j2 *Jail) bool { return j1.Config.Origin < j2.Config.Origin }, OriginDec: func(j1, j2 *Jail) bool { return j1.Config.Origin > j2.Config.Origin }, OwnerInc: func(j1, j2 *Jail) bool { return j1.Config.Owner < j2.Config.Owner }, OwnerDec: func(j1, j2 *Jail) bool { return j1.Config.Owner > j2.Config.Owner }, PcpuInc: func(j1, j2 *Jail) bool { return j1.Config.Pcpu < j2.Config.Pcpu }, PcpuDec: func(j1, j2 *Jail) bool { return j1.Config.Pcpu > j2.Config.Pcpu }, Plugin_nameInc: func(j1, j2 *Jail) bool { return j1.Config.Plugin_name < j2.Config.Plugin_name }, Plugin_nameDec: func(j1, j2 *Jail) bool { return j1.Config.Plugin_name > j2.Config.Plugin_name }, Plugin_repositoryInc: func(j1, j2 *Jail) bool { return j1.Config.Plugin_repository < j2.Config.Plugin_repository }, Plugin_repositoryDec: func(j1, j2 *Jail) bool { return j1.Config.Plugin_repository > j2.Config.Plugin_repository }, PriorityInc: func(j1, j2 *Jail) bool { return j1.Config.Priority < j2.Config.Priority }, PriorityDec: func(j1, j2 *Jail) bool { return j1.Config.Priority > j2.Config.Priority }, PseudoterminalsInc: func(j1, j2 *Jail) bool { return j1.Config.Pseudoterminals < j2.Config.Pseudoterminals }, PseudoterminalsDec: func(j1, j2 *Jail) bool { return j1.Config.Pseudoterminals > j2.Config.Pseudoterminals }, QuotaInc: func(j1, j2 *Jail) bool { return j1.Config.Quota < j2.Config.Quota }, QuotaDec: func(j1, j2 *Jail) bool { return j1.Config.Quota > j2.Config.Quota }, ReadbpsInc: func(j1, j2 *Jail) bool { return j1.Config.Readbps < j2.Config.Readbps }, ReadbpsDec: func(j1, j2 *Jail) bool { return j1.Config.Readbps > j2.Config.Readbps }, ReadiopsInc: func(j1, j2 *Jail) bool { return j1.Config.Readiops < j2.Config.Readiops }, ReadiopsDec: func(j1, j2 *Jail) bool { return j1.Config.Readiops > j2.Config.Readiops }, ReleaseInc: func(j1, j2 *Jail) bool { return j1.Config.Release < j2.Config.Release }, ReleaseDec: func(j1, j2 *Jail) bool { return j1.Config.Release > j2.Config.Release }, ReservationInc: func(j1, j2 *Jail) bool { return j1.Config.Reservation < j2.Config.Reservation }, ReservationDec: func(j1, j2 *Jail) bool { return j1.Config.Reservation > j2.Config.Reservation }, ResolverInc: func(j1, j2 *Jail) bool { return j1.Config.Resolver < j2.Config.Resolver }, ResolverDec: func(j1, j2 *Jail) bool { return j1.Config.Resolver > j2.Config.Resolver }, RlimitsInc: func(j1, j2 *Jail) bool { return j1.Config.Rlimits < j2.Config.Rlimits }, RlimitsDec: func(j1, j2 *Jail) bool { return j1.Config.Rlimits > j2.Config.Rlimits }, RtsoldInc: func(j1, j2 *Jail) bool { return j1.Config.Rtsold < j2.Config.Rtsold }, RtsoldDec: func(j1, j2 *Jail) bool { return j1.Config.Rtsold > j2.Config.Rtsold }, SecurelevelInc: func(j1, j2 *Jail) bool { return j1.Config.Securelevel < j2.Config.Securelevel }, SecurelevelDec: func(j1, j2 *Jail) bool { return j1.Config.Securelevel > j2.Config.Securelevel }, ShmsizeInc: func(j1, j2 *Jail) bool { return j1.Config.Shmsize < j2.Config.Shmsize }, ShmsizeDec: func(j1, j2 *Jail) bool { return j1.Config.Shmsize > j2.Config.Shmsize }, StacksizeInc: func(j1, j2 *Jail) bool { return j1.Config.Stacksize < j2.Config.Stacksize }, StacksizeDec: func(j1, j2 *Jail) bool { return j1.Config.Stacksize > j2.Config.Stacksize }, Stop_timeoutInc: func(j1, j2 *Jail) bool { return j1.Config.Stop_timeout < j2.Config.Stop_timeout }, Stop_timeoutDec: func(j1, j2 *Jail) bool { return j1.Config.Stop_timeout > j2.Config.Stop_timeout }, SwapuseInc: func(j1, j2 *Jail) bool { return j1.Config.Swapuse < j2.Config.Swapuse }, SwapuseDec: func(j1, j2 *Jail) bool { return j1.Config.Swapuse > j2.Config.Swapuse }, Sync_stateInc: func(j1, j2 *Jail) bool { return j1.Config.Sync_state < j2.Config.Sync_state }, Sync_stateDec: func(j1, j2 *Jail) bool { return j1.Config.Sync_state > j2.Config.Sync_state }, Sync_targetInc: func(j1, j2 *Jail) bool { return j1.Config.Sync_target < j2.Config.Sync_target }, Sync_targetDec: func(j1, j2 *Jail) bool { return j1.Config.Sync_target > j2.Config.Sync_target }, Sync_tgt_zpoolInc: func(j1, j2 *Jail) bool { return j1.Config.Sync_tgt_zpool < j2.Config.Sync_tgt_zpool }, Sync_tgt_zpoolDec: func(j1, j2 *Jail) bool { return j1.Config.Sync_tgt_zpool > j2.Config.Sync_tgt_zpool }, SysvmsgInc: func(j1, j2 *Jail) bool { return j1.Config.Sysvmsg < j2.Config.Sysvmsg }, SysvmsgDec: func(j1, j2 *Jail) bool { return j1.Config.Sysvmsg > j2.Config.Sysvmsg }, SysvsemInc: func(j1, j2 *Jail) bool { return j1.Config.Sysvsem < j2.Config.Sysvsem }, SysvsemDec: func(j1, j2 *Jail) bool { return j1.Config.Sysvsem > j2.Config.Sysvsem }, SysvshmInc: func(j1, j2 *Jail) bool { return j1.Config.Sysvshm < j2.Config.Sysvshm }, SysvshmDec: func(j1, j2 *Jail) bool { return j1.Config.Sysvshm > j2.Config.Sysvshm }, TemplateInc: func(j1, j2 *Jail) bool { return j1.Config.Template < j2.Config.Template }, TemplateDec: func(j1, j2 *Jail) bool { return j1.Config.Template > j2.Config.Template }, UsedInc: func(j1, j2 *Jail) bool { return j1.Config.Used < j2.Config.Used }, UsedDec: func(j1, j2 *Jail) bool { return j1.Config.Used > j2.Config.Used }, VmemoryuseInc: func(j1, j2 *Jail) bool { return j1.Config.Vmemoryuse < j2.Config.Vmemoryuse }, VmemoryuseDec: func(j1, j2 *Jail) bool { return j1.Config.Vmemoryuse > j2.Config.Vmemoryuse }, VnetInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet < j2.Config.Vnet }, VnetDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet > j2.Config.Vnet }, Vnet_default_interfaceInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet_default_interface < j2.Config.Vnet_default_interface }, Vnet_default_interfaceDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet_default_interface > j2.Config.Vnet_default_interface }, Vnet_interfacesInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet_interfaces < j2.Config.Vnet_interfaces }, Vnet_interfacesDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet_interfaces > j2.Config.Vnet_interfaces }, Vnet0_macInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet0_mac < j2.Config.Vnet0_mac }, Vnet0_macDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet0_mac > j2.Config.Vnet0_mac }, Vnet1_macInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet1_mac < j2.Config.Vnet1_mac }, Vnet1_macDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet1_mac > j2.Config.Vnet1_mac }, Vnet2_macInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet2_mac < j2.Config.Vnet2_mac }, Vnet2_macDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet2_mac > j2.Config.Vnet2_mac }, Vnet3_macInc: func(j1, j2 *Jail) bool { return j1.Config.Vnet3_mac < j2.Config.Vnet3_mac }, Vnet3_macDec: func(j1, j2 *Jail) bool { return j1.Config.Vnet3_mac > j2.Config.Vnet3_mac }, WallclockInc: func(j1, j2 *Jail) bool { return j1.Config.Wallclock < j2.Config.Wallclock }, WallclockDec: func(j1, j2 *Jail) bool { return j1.Config.Wallclock > j2.Config.Wallclock }, WritebpsInc: func(j1, j2 *Jail) bool { return j1.Config.Writebps < j2.Config.Writebps }, WritebpsDec: func(j1, j2 *Jail) bool { return j1.Config.Writebps > j2.Config.Writebps }, WriteiopsInc: func(j1, j2 *Jail) bool { return j1.Config.Writeiops < j2.Config.Writeiops }, WriteiopsDec: func(j1, j2 *Jail) bool { return j1.Config.Writeiops > j2.Config.Writeiops }, } js := JailSort{ ConfigPathInc: func(j1, j2 *Jail) bool { return j1.ConfigPath < j2.ConfigPath }, ConfigPathDec: func(j1, j2 *Jail) bool { return j1.ConfigPath > j2.ConfigPath }, InternalNameInc: func(j1, j2 *Jail) bool { return j1.InternalName < j2.InternalName }, InternalNameDec: func(j1, j2 *Jail) bool { return j1.InternalName > j2.InternalName }, JIDInc: func(j1, j2 *Jail) bool { return j1.JID < j2.JID }, JIDDec: func(j1, j2 *Jail) bool { return j1.JID > j2.JID }, NameInc: func(j1, j2 *Jail) bool { return j1.Name < j2.Name }, NameDec: func(j1, j2 *Jail) bool { return j1.Name > j2.Name }, RootPathInc: func(j1, j2 *Jail) bool { return j1.RootPath < j2.RootPath }, RootPathDec: func(j1, j2 *Jail) bool { return j1.RootPath > j2.RootPath }, RunningInc: func(j1, j2 *Jail) bool { return !j1.Running && j2.Running }, RunningDec: func(j1, j2 *Jail) bool { return j1.Running && !j2.Running }, ZpoolInc: func(j1, j2 *Jail) bool { return j1.Zpool < j2.Zpool }, ZpoolDec: func(j1, j2 *Jail) bool { return j1.Zpool > j2.Zpool }, Config: jcs, } return js } // multiSorter implements the Sort interface, sorting the jails within. type multiSorter struct { jails []Jail less []lessFunc } // Sort sorts the argument slice according to the less functions passed to OrderedBy. func (ms *multiSorter) Sort(jails []Jail) { ms.jails = jails sort.Sort(ms) } // OrderedBy returns a Sorter that sorts using the less functions, in order. // Call its Sort method to sort the data. func OrderedBy(less ...lessFunc) *multiSorter { return &multiSorter{ less: less, } } // Len is part of sort.Interface. func (ms *multiSorter) Len() int { return len(ms.jails) } // Swap is part of sort.Interface. func (ms *multiSorter) Swap(i, j int) { ms.jails[i], ms.jails[j] = ms.jails[j], ms.jails[i] } // Less is part of sort.Interface. It is implemented by looping along the // less functions until it finds a comparison that discriminates between // the two items (one is less than the other). Note that it can call the // less functions twice per call. We could change the functions to return // -1, 0, 1 and reduce the number of calls for greater efficiency: an // exercise for the reader. func (ms *multiSorter) Less(i, j int) bool { p, q := &ms.jails[i], &ms.jails[j] // Try all but the last comparison. var k int for k = 0; k < len(ms.less)-1; k++ { less := ms.less[k] switch { case less(p, q): // p < q, so we have a decision. return true case less(q, p): // p > q, so we have a decision. return false } // p == q; try the next comparison. } // All comparisons to here said "equal", so just return whatever // the final comparison reports. return ms.less[k](p, q) }