From da74456d6a2a9d56b496b8370e20f5a20aac5dff Mon Sep 17 00:00:00 2001 From: yo Date: Sat, 2 Apr 2022 21:38:54 +0200 Subject: [PATCH] Set property K for int type + write config to disk --- cmd/root.go | 10 ++-- cmd/start.go | 29 ++++++----- cmd/utils.go | 140 +++++++++++++-------------------------------------- 3 files changed, 57 insertions(+), 122 deletions(-) diff --git a/cmd/root.go b/cmd/root.go index 890992b..614b025 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -12,7 +12,7 @@ import ( ) const ( - gVersion = "0.022b" + gVersion = "0.023" ) var ( @@ -188,12 +188,16 @@ func cleanAfterRun() { for _, j := range gJails { if j.ConfigUpdated { // TODO : Marshall to disk - fmt.Printf("Config for jail %s will be updated\n", j.Name) + //fmt.Printf("Config for jail %s will be updated\n", j.Name) marshaled, err := json.MarshalIndent(j.Config, "", " ") if err != nil { fmt.Printf("ERROR marshaling config: %s\n", err.Error()) } - fmt.Printf(string(marshaled)) + //fmt.Printf(string(marshaled)) + if os.WriteFile(j.ConfigPath, []byte(marshaled), 0644); err != nil { + fmt.Printf("Error writing config file %s: %v\n", j.ConfigPath, err) + os.Exit(1) + } } } } diff --git a/cmd/start.go b/cmd/start.go index db18b5d..c38089e 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -9,7 +9,7 @@ import ( // "os/exec" // "reflect" "strings" -// "strconv" + "strconv" ) func SetJailProperties(args []string) { @@ -55,6 +55,7 @@ func SetJailProperties(args []string) { } } +// TODO : Support types. For now we just update int, other types will crash // WIP. Not working now (need to address the real struct field, not a copy of it) // setJailProperty takes a string as propValue, whatever the real property type is. // It will be converted. @@ -88,23 +89,24 @@ func setJailProperty(jail *Jail, propName string, propValue string) error { return errors.New(fmt.Sprintf("Property %s have an unsupported type in setJailProperty!\n", propName)) }*/ - // panic: reflect: reflect.Value.Set using unaddressable value - //val.Set(reflect.ValueOf(propValue).Elem()) - // ...Because val settability is false :-( - fmt.Printf("settability of val %s: %v\n", val.Interface(), val.CanSet()) - - // This is OK, using the index to get the real jail object - //gJails[i].Config.Allow_mlock = 1 - - - // TODO : integrate this function - //setJailConfigUpdated(jail) + if val.CanSet() { + ival, err := strconv.Atoi(propValue) + if err != nil { + return err + } + val.SetInt(int64(ival)) + 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 } +// FIXME : Do not work?! // We cant use internalName as the value exist only when jail is running func setJailConfigUpdated(jail *Jail) error { if len(jail.ConfigPath) == 0 { @@ -112,7 +114,8 @@ func setJailConfigUpdated(jail *Jail) error { } for i, j := range gJails { - if jail.ConfigPath == j.ConfigPath { + if jail.Name == j.Name { + fmt.Printf("Tag %s as configUpdated\n", jail.Name) gJails[i].ConfigUpdated = true return nil } diff --git a/cmd/utils.go b/cmd/utils.go index 7c5dfcc..2f87ec5 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -206,116 +206,44 @@ func getStructFieldValue(parentStruct interface{}, fieldName string) (*reflect.V } } - if strings.Contains(fieldName, ".") { - - // 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 { - 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() - } + 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 } } - } 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 { + 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() + } } return &v, fieldName, nil