From f40db69b9d1f007c6a5a3a31072b03446e4fd131 Mon Sep 17 00:00:00 2001 From: yo Date: Sat, 2 Apr 2022 21:15:06 +0200 Subject: [PATCH] WIP: Implementing setJailProperty, add recursivity to getStructFieldValue --- cmd/start.go | 11 +++-- cmd/utils.go | 116 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 115 insertions(+), 12 deletions(-) diff --git a/cmd/start.go b/cmd/start.go index 2d4638e..db18b5d 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -47,7 +47,11 @@ func SetJailProperties(args []string) { } for _, p := range props { - setJailProperty(&jail, p.name, p.value) + err := setJailProperty(&jail, p.name, p.value) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return + } } } @@ -66,8 +70,9 @@ 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 errors.New(fmt.Sprintf("Field not found: %s", propName)) + return err } /*if kind == "string" { @@ -93,7 +98,7 @@ func setJailProperty(jail *Jail, propName string, propValue string) error { // TODO : integrate this function - setJailConfigUpdated(jail) + //setJailConfigUpdated(jail) } } diff --git a/cmd/utils.go b/cmd/utils.go index 8f4ad01..7c5dfcc 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -188,10 +188,14 @@ func getStructFieldNames(parentStruct interface{}, result []string, prefix strin func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.Value, string, error) { v := reflect.ValueOf(parentStruct) - if v.Kind() == reflect.Ptr { - fmt.Printf("We got a pointer, get Elem form it\n") - v = v.Elem() + // Get value while we're dealing with pointers + for ; v.Kind() == reflect.Ptr ; v = v.Elem() {} + + if v.Kind() != reflect.Struct { + return &v, fieldName, errors.New(fmt.Sprintf("parentStruct is not a struct! Kind: %s", v.Kind().String())) } + + typeOfV := v.Type() if false { for i := 0 ; i < v.NumField(); i++ { @@ -203,17 +207,111 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V } if strings.Contains(fieldName, ".") { - fs := strings.Split(fieldName, ".") - f := v.FieldByName(fs[0]) - //f := v.Elem().FieldByName(fs[0]) - if f.Kind() == reflect.Struct { - return getStructFieldValue(f.Interface(), strings.Join(fs[1:], ".")) + + // Le code degueulasse mais qui marche + legacy := false + + if legacy { + fs := strings.Split(fieldName, ".") + fmt.Printf("Dealing with field \"%s\" of struct \"%s\"\n", strings.Join(fs[1:], "."), fs[0]) + var f reflect.Value + var found bool + for i := 0 ; i < v.NumField() ; i++ { + if typeOfV.Field(i).Name == fs[0] { + f = v.Field(i) + found = true + break + } + } + if !found { + return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName)) + } + + for ; f.Kind() == reflect.Ptr ; { + fmt.Printf("We got a pointer as a nested field, get Elem form it\n") + f = f.Elem() + } + + fmt.Printf("v.kind() = %v\n", v.Kind().String()) + fmt.Printf("v = %v\n", v) + fmt.Printf("f.kind() = %v\n", f.Kind().String()) + fmt.Printf("f = %v\n", f) + /*if f.Kind() == reflect.Ptr { + fmt.Printf("We got a pointer as a nested field, get Elem form it\n") + f = f.Elem() + }*/ + //f := v.Elem().FieldByName(fs[0]) + if f.Kind() == reflect.Struct { + //return getStructFieldValue(&f, strings.Join(fs[1:], ".")) + //return getStructFieldValue(f, strings.Join(fs[1:], ".")) + + + /* GRUIIIK */ + + g := f.FieldByName(fs[1]) + fmt.Printf("get substruct field, f.kind() = %v\n", f.Kind().String()) + fmt.Printf("get substruct field, g.kind() = %v\n", g.Kind().String()) + fmt.Printf("get substruct field, f = %v\n", f) + fmt.Printf("get substruct field, g = %v\n", g) + if g.IsValid() { + fmt.Printf("Return g = %v of Kind %s\n", g, g.Kind().String()) + return &g, fieldName, nil + } else { + return &f, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName)) + } + + /* FIN DE GRUIIIIK */ + } else { + log.Fatalln(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String())) + } } else { - log.Fatalln(fmt.Sprintf("%s is not a struct: %s\n", fs[0], f.Kind().String())) + var f reflect.Value + var found bool + fs := strings.Split(fieldName, ".") + // Loop through properties + for i, curF := range fs { + found = false + for j := 0 ; j < v.NumField() ; j++ { + if typeOfV.Field(j).Name == curF { + f = v.Field(j) + found = true + break + } + } + if !found { + return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName)) + } + + for ; f.Kind() == reflect.Ptr ; f = f.Elem() {} + + /*fmt.Printf("v.kind() = %v\n", v.Kind().String()) + fmt.Printf("v = %v\n", v) + fmt.Printf("f.kind() = %v\n", f.Kind().String()) + fmt.Printf("f = %v\n", f)*/ + + // If this is the last loop, return result even if it's a struct + // FIXME : What if we got interface? + if f.Kind() != reflect.Struct && i < len(fs)-1 { + if f.IsValid() { + //fmt.Printf("Return f = %v of Kind %s\n", f, f.Kind().String()) + return &f, fieldName, nil + } else { + return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName)) + } + } else { + v = f + typeOfV = v.Type() + } + } } } else { f := v.FieldByName(fieldName) + fmt.Printf("No substruct, v.kind() = %v\n", v.Kind().String()) + fmt.Printf("No substruct, f.kind() = %v\n", f.Kind().String()) + fmt.Printf("No substruct, v = %v\n", v) + fmt.Printf("No substruct, f = %v\n", f) if f.IsValid() { + fmt.Printf("Return f = %v of Kind %s\n", f, f.Kind().String()) return &f, fieldName, nil } else { return &v, fieldName, errors.New(fmt.Sprintf("Field not found: %s", fieldName))