diff --git a/cmd/properties.go b/cmd/properties.go new file mode 100644 index 0000000..86d397d --- /dev/null +++ b/cmd/properties.go @@ -0,0 +1,150 @@ +package cmd + +import ( + "fmt" + "errors" + "reflect" + "strings" + "strconv" +) + +func GetJailProperties(args []string) { + var props []string + var jail Jail + + if len(args) > 0 { + for i, a := range args { + // Last arg is the jail name + if i == len(args)-1 { + jail.Name = a + } else { + props = append(props, a) + } + } + } + + if len(jail.Name) == 0 || len(args) == 0 { + // TODO : Show help + fmt.Printf("Error\n") + return + } + + for _, p := range props { + v, err := getJailProperty(&jail, p) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return + } else { + fmt.Printf("%s = %s\n", p, v) + } + } +} + +func getJailProperty(jail *Jail, propName string) (string, error) { + for i, j := range gJails { + if j.Name == jail.Name { + val, _, err := getStructFieldValue(&gJails[i], propName) + if err != nil { + return "", err + } + + switch val.Kind() { + case reflect.String: + return val.String(), nil + case reflect.Int: + return strconv.FormatInt(val.Int(), 10), nil + case reflect.Bool: + return strconv.FormatBool(val.Bool()), nil + default: + return "", errors.New(fmt.Sprintf("Error: Unknown type for property %s: %s\n", propName, val.Kind())) + } + } + } + + return "", errors.New(fmt.Sprintf("Jail not found: %s", jail.Name)) +} + +func SetJailProperties(args []string) { + type properties struct { + name string + value string + } + + var jail Jail + var props []properties + + if len(args) > 0 { + for i, a := range args { + // This is the jail name + if i == len(args)-1 { + jail.Name = a + } else { + kv := strings.Split(a, "=") + if len(kv) != 2 { + // TODO : Show help + fmt.Printf("Error parsing args: %s\n", a) + return + } else { + p := properties{name: kv[0], value: kv[1]} + props = append(props, p) + } + } + } + } + + if len(jail.Name) == 0 || len(args) == 0 { + // TODO : Show help + fmt.Printf("Error\n") + return + } + + for _, p := range props { + err := setJailProperty(&jail, p.name, p.value) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return + } + } +} + +// setJailProperty takes a string as propValue, whatever the real property type is. +// It will be converted. +func setJailProperty(jail *Jail, propName string, propValue string) error { + for i, j := range gJails { + if j.Name == jail.Name { + val, _, err := getStructFieldValue(&gJails[i], propName) + //val, _, err := getStructFieldValue(&gJails[i].Config, strings.Split(propName, ".")[1]) + if err != nil { + return err + } + + if val.CanSet() { + switch val.Kind() { + case reflect.String: + val.SetString(propValue) + case reflect.Int: + ival, err := strconv.ParseInt(propValue, 10, 64) + if err != nil { + return err + } + val.SetInt(ival) + case reflect.Bool: + bval, err := strconv.ParseBool(propValue) + if err != nil { + return err + } + val.SetBool(bval) + default: + return errors.New(fmt.Sprintf("Field is an unkown type: %s: %s", propName, val.Kind().String())) + } + fmt.Printf("%s: %s set to %s\n", jail.Name, propName, propValue) + gJails[i].ConfigUpdated = true + } else { + return errors.New(fmt.Sprintf("Field is not writable : %s", propName)) + } + } + } + + return nil +} +