diff options
| author | dautor <karlo98.m@gmail.com> | 2024-11-17 20:53:51 +0100 |
|---|---|---|
| committer | dautor <karlo98.m@gmail.com> | 2024-11-17 20:53:51 +0100 |
| commit | f1e579bc427df418af96da61498fe0cdb4cecb69 (patch) | |
| tree | 1fc8f6b196fbc1cc9166a1e10c74eff83f8f2aab /src/module.jail/state.c | |
| parent | c22c6581ee39688785476fe56f2b759ae49ca04a (diff) | |
Add COPYRIGHT and rename module directories
Diffstat (limited to 'src/module.jail/state.c')
| -rw-r--r-- | src/module.jail/state.c | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/src/module.jail/state.c b/src/module.jail/state.c new file mode 100644 index 0000000..893961e --- /dev/null +++ b/src/module.jail/state.c @@ -0,0 +1,396 @@ +#include "state.h" + +// FREE + +void +Free_interface_configuration(interface_configuration *E) +{ + free(E->Name); + switch(E->Type) + { + case interface_type_eiface: break; + case interface_type_steal: free(E->steal.Interface); break; + case interface_type_COUNT: + default: __builtin_unreachable(); + } +} + +void +Free_interfaces_configuration(interfaces_configuration *E) +{ + for(size_t i = 0; i < E->Count; ++i) Free_interface_configuration(E->_ + i); + free(E->_); +} + +void +Free_mapping(mapping *E) +{ + free(E->Source); + free(E->Target); +} + +void +Free_filesystem_configuration(filesystem_configuration *E) +{ + for(size_t i = 0; i < E->LayerCount; ++i) free(E->Layer[i]); + if(E->Layer != NULL) free(E->Layer); + if(E->Temporary != NULL) free(E->Temporary); + for(size_t i = 0; i < E->VolumeCount; ++i) Free_mapping(E->Volume + i); + if(E->Volume != NULL) free(E->Volume); +} + +void +Free_configuration(configuration *E) +{ + Free_filesystem_configuration(&E->Filesystem); + Free_interfaces_configuration(&E->Interfaces); + Free_string_array(&E->Init); + Free_string_array(&E->Shutdown); +} + +void +Free_interface(interface *E) +{ + UNUSED(E); +} + +void +Free_interfaces(interfaces *E) +{ + for(size_t i = 0; i < E->Count; ++i) Free_interface(E->_ + i); + free(E->_); +} + +void +Free_data(data *E) +{ + Free_interfaces(&E->Interfaces); +} + +// PARSE + +char * +Parse_interface_type(interface_type *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(STRING); + char const *Type = ucl_object_tostring(root); + for(interface_type i = 0; i < interface_type_COUNT; ++i) + { + if(strcmp(interface_type_Names[i], Type) == 0) + { + *E = i; + return NULL; + } + } + asprintf(&Error, "%s invalid interface type '%s'", Position, Type); + goto error; +error: + return Error; +} + +char * +Parse_interface_configuration(interface_configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + { + char *NewPosition; + asprintf(&NewPosition, "%s.type", Position); + Error = Parse_interface_type(&E->Type, ucl_object_lookup(root, "type"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + switch(E->Type) + { + case interface_type_eiface: break; + case interface_type_steal: + { + ucl_object_t const *interface = ucl_object_lookup(root, "interface"); + UCL_CHECK(interface, STRING); + E->steal.Interface = strdup(ucl_object_tostring(interface)); + break; + } + case interface_type_COUNT: + default: __builtin_unreachable(); + } + return NULL; +error: + return Error; +} + +char * +Parse_interfaces_configuration(interfaces_configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + E->Count = root->len; + E->_ = calloc(sizeof(interface_configuration), E->Count); + { + ucl_object_iter_t it = NULL; + for(E->Count = 0; E->Count < root->len; ++E->Count) + { + ucl_object_t const *v = ucl_iterate_object(root, &it, true); + if(v == NULL) break; + char const *k = ucl_object_key(v); + if(k == NULL) continue; + interface_configuration *I = E->_ + E->Count; + char *NewPosition; + asprintf(&NewPosition, "%s['%s']", Position, k); + Error = Parse_interface_configuration(I, v, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + I->Name = strdup(k); + } + } + return NULL; +error: + Free_interfaces_configuration(E); + return Error; +} + +char * +Parse_mapping(mapping *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *source = ucl_object_lookup(root, "source"); + UCL_CHECK(source, STRING); + ucl_object_t const *target = ucl_object_lookup(root, "target"); + UCL_CHECK(target, STRING); + E->Source = strdup(ucl_object_tostring(source)); + E->Target = strdup(ucl_object_tostring(target)); + return NULL; +error: + return Error; +} + +char * +Parse_filesystem_configuration(filesystem_configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *layers = ucl_object_lookup(root, "layers"); + UCL_CHECK_OPTIONAL(layers, ARRAY); + ucl_object_t const *temporary = ucl_object_lookup(root, "temporary"); + UCL_CHECK_OPTIONAL(temporary, STRING); + ucl_object_t const *volumes = ucl_object_lookup(root, "volumes"); + UCL_CHECK_OPTIONAL(volumes, ARRAY); + ucl_object_t const *devfs = ucl_object_lookup(root, "devfs"); + UCL_CHECK_OPTIONAL(devfs, INT); + if(layers != NULL) + { + E->Layer = calloc(sizeof(char *), layers->len); + ucl_object_iter_t it = NULL; + for(E->LayerCount = 0; E->LayerCount < layers->len; ++E->LayerCount) + { + ucl_object_t const *v = ucl_iterate_object(layers, &it, true); + if(v == NULL) break; + char const *k = ucl_object_key(v); + if(k != NULL) continue; + if(v->type != UCL_STRING) + { + asprintf(&Error, "%s.layers[%zu] is not " UCL_CHECK_HELPER(STRING), Position, E->LayerCount); + goto error; + } + E->Layer[E->LayerCount] = strdup(ucl_object_tostring(v)); + } + } + if(temporary != NULL) E->Temporary = strdup(ucl_object_tostring(temporary)); + if(volumes != NULL) + { + E->Volume = calloc(sizeof(mapping), volumes->len); + ucl_object_iter_t it = NULL; + for(E->VolumeCount = 0; E->VolumeCount < volumes->len; ++E->VolumeCount) + { + ucl_object_t const *v = ucl_iterate_object(volumes, &it, true); + if(v == NULL) break; + char const *k = ucl_object_key(v); + if(k != NULL) continue; + mapping *I = E->Volume + E->VolumeCount; + char *NewPosition; + asprintf(&NewPosition, "%s.volumes[%zu]", Position, E->VolumeCount); + Error = Parse_mapping(I, v, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + } + E->DevfsRuleset = ucl_object_toint(devfs); + return NULL; +error: + Free_filesystem_configuration(E); + return Error; +} + +char * +Parse_configuration(configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + { + char *NewPosition; + asprintf(&NewPosition, "%s.interfaces", Position); + Error = + Parse_interfaces_configuration(&E->Interfaces, ucl_object_lookup(root, "interfaces"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + { + char *NewPosition; + asprintf(&NewPosition, "%s.filesystem", Position); + Error = + Parse_filesystem_configuration(&E->Filesystem, ucl_object_lookup(root, "filesystem"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + { + char *NewPosition; + asprintf(&NewPosition, "%s.init", Position); + Error = Parse_string_array(&E->Init, ucl_object_lookup(root, "init"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + { + char *NewPosition; + asprintf(&NewPosition, "%s.shutdown", Position); + Error = Parse_string_array(&E->Shutdown, ucl_object_lookup(root, "shutdown"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + return NULL; +error: + return Error; +} + +char * +Parse_interface(interface *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + { + char *NewPosition; + asprintf(&NewPosition, "%s.type", Position); + Error = Parse_interface_type(&E->Type, ucl_object_lookup(root, "type"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + switch(E->Type) + { + case interface_type_eiface: + { + ucl_object_t const *id = ucl_object_lookup(root, "id"); + UCL_CHECK(id, INT); + s64 ID = ucl_object_toint(id); + if(ID < 0 || ID > INT32_MAX) + { + asprintf(&Error, "%s id invalid (%ld)", Position, ID); + goto error; + } + E->ID = (u32)ID; + break; + } + case interface_type_steal: break; + case interface_type_COUNT: + default: __builtin_unreachable(); + } + return NULL; +error: + return Error; +} + +char * +Parse_interfaces(interfaces *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(ARRAY); + E->Count = root->len; + E->_ = calloc(sizeof(interface_configuration), E->Count); + { + ucl_object_iter_t it = NULL; + for(E->Count = 0; E->Count < root->len; ++E->Count) + { + ucl_object_t const *v = ucl_iterate_object(root, &it, true); + if(v == NULL) break; + char const *k = ucl_object_key(v); + if(k != NULL) continue; + interface *I = E->_ + E->Count; + char *NewPosition; + asprintf(&NewPosition, "%s['%zu']", Position, E->Count); + Error = Parse_interface(I, v, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + } + return NULL; +error: + Free_interfaces(E); + return Error; +} + +char * +Parse_data(data *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *jid = ucl_object_lookup(root, "jid"); + UCL_CHECK(jid, INT); + int64_t JID = ucl_object_toint(jid); + if(JID < 0 || JID > INT32_MAX) + { + asprintf(&Error, "%s jid invalid (%ld)", Position, JID); + goto error; + } + E->JID = (jid_t)JID; + { + char *NewPosition; + asprintf(&NewPosition, "%s.interfaces", Position); + Error = Parse_interfaces(&E->Interfaces, ucl_object_lookup(root, "interfaces"), NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + } + return NULL; +error: + return Error; +} + +// SAVE + +void +Save_interface(jprint_state *S, interface const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "type"); + JPrint_string(S, interface_type_Names[E->Type]); + switch(E->Type) + { + case interface_type_eiface: + { + JPrintMember(S, "id"); + JPrint_ssize_t(S, E->ID); + break; + } + case interface_type_steal: break; + case interface_type_COUNT: + default: __builtin_unreachable(); + } + JPrintObjectEnd(S); +} + +void +Save_interfaces(jprint_state *S, interfaces const *E) +{ + JPrintArrayBegin(S); + for(size_t i = 0; i < E->Count; ++i) Save_interface(S, E->_ + i); + JPrintArrayEnd(S); +} + +void +Save_data(jprint_state *S, data const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "jid"); + JPrint_ssize_t(S, E->JID); + JPrintMember(S, "interfaces"); + Save_interfaces(S, &E->Interfaces); + JPrintObjectEnd(S); +} |
