/** * _ImageData_assign - utility function to write data into ImageData structure when * parsing configuration file. * * Parameters: * key - identifier from configuration file * value - value from configuration file * t_image - anonymous pointer which *should* point to an ImageData structure * * Returns: * 0 if value successfully set or appended * 1 if invalid input * 2 invalid key */ int _ImageData_assign(const char *key, const char *value, void *t_image) { ImageData *image = (ImageData *) t_image; if (image == NULL || key == NULL || value == NULL) { return 1; } if (strcmp(key, "FORMAT") == 0) { if (strcmp(value, "VFS") == 0) { image->format = FORMAT_VFS; } else if (strcmp(value, "ext4") == 0) { image->format = FORMAT_EXT4; } else if (strcmp(value, "squashfs") == 0) { image->format = FORMAT_SQUASHFS; } else if (strcmp(value, "cramfs") == 0) { image->format = FORMAT_CRAMFS; } else if (strcmp(value, "xfs") == 0) { image->format = FORMAT_XFS; } else { image->format = FORMAT_INVALID; } } else if (strcmp(key, "ENV") == 0) { char **tmp = image->env + image->env_size; strncpy_StringArray(value, strlen(value), &tmp, &(image->env), &(image->env_capacity), ENV_ALLOC_SIZE); image->env_size++; } else if (strcmp(key, "ENTRY") == 0) { image->entryPoint = strdup(value); if (image->entryPoint == NULL) { return 1; } } else if (strcmp(key, "WORKDIR") == 0) { image->workdir = strdup(value); if (image->workdir == NULL) { return 1; } } else if (strcmp(key, "VOLUME") == 0) { char **tmp = image->volume + image->volume_size; char *tvalue = _ImageData_filterString(value, 1); strncpy_StringArray(tvalue, strlen(tvalue), &tmp, &(image->volume), &(image->volume_capacity), VOL_ALLOC_SIZE); image->volume_size++; free(tvalue); } else { printf("Couldn't understand key: %s\n", key); return 2; } return 0; }
int _parseVolumeMap( const char *input, VolumeMap *volMap, int (*_validate_fp)(const char *, const char *, VolumeMapFlag *), short requireTo ) { if (input == NULL || volMap == NULL) return 1; char **rawPtr = volMap->raw + volMap->n; char **toPtr = volMap->to + volMap->n; char **fromPtr = volMap->from + volMap->n; VolumeMapFlag **flagPtr = volMap->flags + volMap->n; const char *ptr = input; const char *eptr = NULL; char *tmp = NULL; size_t len = strlen(input); int ret = 0; char *to = NULL; char *from = NULL; VolumeMapFlag *flags = NULL; size_t flagsCapacity = 0; char *raw = NULL; char **tokens = NULL; char **tk_ptr = NULL; size_t tokenIdx = 0; size_t rawLen = 0; size_t rawCapacity = 0; size_t flagIdx = 0; size_t flagCnt = 0; while (ptr < input + len) { size_t ntokens = 0; eptr = _findEndVolumeMapString(ptr); if (eptr == ptr && eptr != NULL) { ptr++; continue; } if (eptr == NULL) { break; } /* make copy for parsing */ tmp = (char *) malloc(sizeof(char) * (eptr - ptr + 1)); if (tmp == NULL) { fprintf(stderr, "Failed to allocate memory for tmp string\n"); goto _parseVolumeMap_unclean; } strncpy(tmp, ptr, eptr - ptr); tmp[eptr - ptr] = 0; char *volMapStr = tmp; if (*volMapStr == '"' && *(volMapStr + (eptr - ptr) - 1) == '"') { *(volMapStr + (eptr - ptr) - 1) = 0; volMapStr++; } /* tokenize the the input string */ tokens = _tokenizeVolumeMapInput(volMapStr); /* count how many non-NULL tokens there are */ for (ntokens = 0; tokens && tokens[ntokens]; ntokens++) { } if (tokens == NULL || ntokens == 0) { fprintf(stderr, "Failed to parse VolumeMap tokens from \"%s\"," " aborting!\n", tmp); goto _parseVolumeMap_unclean; } from = userInputPathFilter(tokens[0], 1); to = userInputPathFilter(tokens[1], 1); for (tokenIdx = 2; tokenIdx < ntokens; tokenIdx++) { if (_parseFlag(tokens[tokenIdx], &flags, &flagsCapacity) != 0) { fprintf(stderr, "Invalid mount flags specified: %s\n", tokens[tokenIdx]); goto _parseVolumeMap_unclean; } } /* if we only got a from and to is not required assume we are binding a path from outside the container and to can be set to from */ if (from && ntokens == 1 && !requireTo) { to = strdup(from); } /* ensure the user is asking for a legal mapping */ if ((ret = _validate_fp(from, to, flags)) != 0) { fprintf(stderr, "Invalid Volume Map: %.*s, aborting! %d\n", (int) (eptr - ptr), ptr, ret ); goto _parseVolumeMap_unclean; } if (to == NULL || from == NULL) { fprintf(stderr, "INVALID format for volume map %.*s\n", (int) (eptr - ptr), ptr ); goto _parseVolumeMap_unclean; } for (flagCnt = 0; flags && flags[flagCnt].type != 0; flagCnt++) { } if (flagCnt > 0) { qsort(flags, flagCnt, sizeof(VolumeMapFlag), _cmpFlags); } /* generate a new "raw" string from the filtered values */ rawLen = 2 + strlen(from) + strlen(to); raw = (char *) malloc(sizeof(char) * rawLen); rawCapacity = sizeof(char) * rawLen; rawLen = snprintf(raw, rawLen, "%s:%s", from, to); for (flagIdx = 0; flagIdx < flagCnt; flagIdx++) { if (flags[flagIdx].type == VOLMAP_FLAG_READONLY) { raw = alloc_strcatf(raw, &rawLen, &rawCapacity, ":ro"); } else if (flags[flagIdx].type == VOLMAP_FLAG_RECURSIVE) { raw = alloc_strcatf(raw, &rawLen, &rawCapacity, ":rec"); } else if (flags[flagIdx].type == VOLMAP_FLAG_SLAVE) { raw = alloc_strcatf(raw, &rawLen, &rawCapacity, ":slave"); } else if (flags[flagIdx].type == VOLMAP_FLAG_PRIVATE) { raw = alloc_strcatf(raw, &rawLen, &rawCapacity, ":private"); } else if (flags[flagIdx].type == VOLMAP_FLAG_PERNODECACHE) { VolMapPerNodeCacheConfig *cache = (VolMapPerNodeCacheConfig *) flags[flagIdx].value; if (cache == NULL) { fprintf(stderr, "FAILED to read perNodeCache config from memory\n"); goto _parseVolumeMap_unclean; } raw = alloc_strcatf(raw, &rawLen, &rawCapacity, ":perNodeCache=size=%lu,bs=%lu,method=%s,fstype=%s", cache->cacheSize, cache->blockSize, cache->method, cache->fstype); } } /* append to raw array */ ret = strncpy_StringArray(raw, rawLen, &rawPtr, &(volMap->raw), &(volMap->rawCapacity), VOLUME_ALLOC_BLOCK); if (ret != 0) goto _parseVolumeMap_unclean; ret = strncpy_StringArray(to, strlen(to), &toPtr, &(volMap->to), &(volMap->toCapacity), VOLUME_ALLOC_BLOCK); if (ret != 0) goto _parseVolumeMap_unclean; ret = strncpy_StringArray(from, strlen(from), &fromPtr, &(volMap->from), &(volMap->fromCapacity), VOLUME_ALLOC_BLOCK); if (ret != 0) goto _parseVolumeMap_unclean; if (volMap->n >= volMap->flagsCapacity) { VolumeMapFlag **tmp = (VolumeMapFlag **) realloc(volMap->flags, sizeof(VolumeMapFlag *) * (volMap->flagsCapacity + VOLUME_ALLOC_BLOCK)); if (tmp == NULL) { fprintf(stderr, "Failed to allocate memory!\n"); goto _parseVolumeMap_unclean; } volMap->flags = tmp; flagPtr = volMap->flags + volMap->n; volMap->flagsCapacity += VOLUME_ALLOC_BLOCK; memset(flagPtr, 0, sizeof(VolumeMapFlag *) * (volMap->flagsCapacity - volMap->n)); } *flagPtr++ = flags; *flagPtr = NULL; if (ret != 0) goto _parseVolumeMap_unclean; if (from != NULL) free(from); if (to != NULL) free(to); if (raw != NULL) free(raw); from = NULL; to = NULL; raw = NULL; flags = NULL; ptr = eptr + 1; volMap->n += 1; if (tmp != NULL) free(tmp); tmp = NULL; for (tk_ptr = tokens; tk_ptr && *tk_ptr; tk_ptr++) { free(*tk_ptr); } if (tokens != NULL) free(tokens); tokens = NULL; } return 0; _parseVolumeMap_unclean: { char *freeArray[] = {tmp, from, to, raw, NULL}; char **freePtr = NULL; for (freePtr = freeArray; *freePtr != NULL; freePtr++) { if (*freePtr != NULL) { free(*freePtr); } } for (tk_ptr = tokens; tk_ptr && *tk_ptr; tk_ptr++) { free(*tk_ptr); } if (tokens != NULL) free(tokens); tokens = NULL; if (flags != NULL) { free_VolumeMapFlag(flags, 1); flags = NULL; } } return 1; }
static int _assign(const char *key, const char *value, void *t_config) { UdiRootConfig *config = (UdiRootConfig *)t_config; if (strcmp(key, "udiMount") == 0) { config->udiMountPoint = strdup(value); if (config->udiMountPoint == NULL) return 1; } else if (strcmp(key, "loopMount") == 0) { config->loopMountPoint = strdup(value); if (config->loopMountPoint == NULL) return 1; } else if (strcmp(key, "imagePath") == 0) { config->imageBasePath = strdup(value); if (config->imageBasePath == NULL) return 1; } else if (strcmp(key, "udiRootPath") == 0) { config->udiRootPath = strdup(value); if (config->udiRootPath == NULL) return 1; } else if (strcmp(key, "perNodeCachePath") == 0) { config->perNodeCachePath = strdup(value); } else if (strcmp(key, "perNodeCacheSizeLimit") == 0) { config->perNodeCacheSizeLimit = parseBytes(value); } else if (strcmp(key, "perNodeCacheAllowedFsType") == 0) { char *valueDup = strdup(value); char *search = valueDup; char *svPtr = NULL; char *ptr = NULL; while ((ptr = strtok_r(search, " ", &svPtr)) != NULL) { char **pncPtr = config->perNodeCacheAllowedFsType + config->perNodeCacheAllowedFsType_size; strncpy_StringArray(ptr, strlen(ptr), &pncPtr, &(config->perNodeCacheAllowedFsType), &(config->perNodeCacheAllowedFsType_capacity), PNCALLOWEDFS_ALLOC_BLOCK); config->perNodeCacheAllowedFsType_size++; search = NULL; } free(valueDup); } else if (strcmp(key, "sitePreMountHook") == 0) { config->sitePreMountHook = strdup(value); if (config->sitePreMountHook == NULL) return 1; } else if (strcmp(key, "sitePostMountHook") == 0) { config->sitePostMountHook = strdup(value); if (config->sitePostMountHook == NULL) return 1; } else if (strcmp(key, "optUdiImage") == 0) { config->optUdiImage = strdup(value); if (config->optUdiImage == NULL) return 1; } else if (strcmp(key, "etcPath") == 0) { config->etcPath = strdup(value); if (config->etcPath == NULL) return 1; } else if (strcmp(key, "allowLocalChroot") == 0) { config->allowLocalChroot = atoi(value) != 0; } else if (strcmp(key, "autoLoadKernelModule") == 0) { config->autoLoadKernelModule = atoi(value); } else if (strcmp(key, "mountPropagationStyle") == 0) { if (strcmp(value, "private") == 0) { config->mountPropagationStyle = VOLMAP_FLAG_PRIVATE; } else if (strcmp(value, "slave") == 0) { config->mountPropagationStyle = VOLMAP_FLAG_SLAVE; } else { return 1; } } else if (strcmp(key, "mountUdiRootWritable") == 0) { config->mountUdiRootWritable = atoi(value); } else if (strcmp(key, "maxGroupCount") == 0) { config->maxGroupCount = strtoul(value, NULL, 10); } else if (strcmp(key, "modprobePath") == 0) { config->modprobePath = strdup(value); } else if (strcmp(key, "insmodPath") == 0) { config->insmodPath = strdup(value); } else if (strcmp(key, "cpPath") == 0) { config->cpPath = strdup(value); } else if (strcmp(key, "mvPath") == 0) { config->mvPath = strdup(value); } else if (strcmp(key, "chmodPath") == 0) { config->chmodPath = strdup(value); } else if (strcmp(key, "ddPath") == 0) { config->ddPath = strdup(value); } else if (strcmp(key, "mkfsXfsPath") == 0) { config->mkfsXfsPath = strdup(value); } else if (strcmp(key, "rootfsType") == 0) { config->rootfsType = strdup(value); } else if (strcmp(key, "gatewayTimeout") == 0) { config->gatewayTimeout = strtoul(value, NULL, 10); } else if (strcmp(key, "kmodBasePath") == 0) { struct utsname uts; memset(&uts, 0, sizeof(struct utsname)); if (uname(&uts) != 0) { fprintf(stderr, "FAILED to get uname data!\n"); return 1; } config->kmodBasePath = strdup(value); if (config->kmodBasePath == NULL) return 1; config->kmodPath = alloc_strgenf("%s/%s", config->kmodBasePath, uts.release); } else if (strcmp(key, "kmodCacheFile") == 0) { config->kmodCacheFile = strdup(value); if (config->kmodCacheFile == NULL) return 1; } else if (strcmp(key, "siteFs") == 0) { if (config->siteFs == NULL) { config->siteFs = (VolumeMap *) malloc(sizeof(VolumeMap)); memset(config->siteFs, 0, sizeof(VolumeMap)); } if (parseVolumeMapSiteFs(value, config->siteFs) != 0) { fprintf(stderr, "FAILED to parse siteFs volumeMap\n"); return 1; } } else if (strcmp(key, "siteEnv") == 0) { char *valueDup = strdup(value); char *search = valueDup; char *svPtr = NULL; char *ptr = NULL; while ((ptr = strtok_r(search, " ", &svPtr)) != NULL) { char **siteEnvPtr = config->siteEnv + config->siteEnv_size; strncpy_StringArray(ptr, strlen(ptr), &siteEnvPtr, &(config->siteEnv), &(config->siteEnv_capacity), SITEFS_ALLOC_BLOCK); config->siteEnv_size++; search = NULL; } free(valueDup); } else if (strcmp(key, "siteEnvAppend") == 0) { char *valueDup = strdup(value); char *search = valueDup; char *svPtr = NULL; char *ptr = NULL; while ((ptr = strtok_r(search, " ", &svPtr)) != NULL) { char **siteEnvAppendPtr = config->siteEnvAppend + config->siteEnvAppend_size; strncpy_StringArray(ptr, strlen(ptr), &siteEnvAppendPtr, &(config->siteEnvAppend), &(config->siteEnvAppend_capacity), SITEFS_ALLOC_BLOCK); config->siteEnvAppend_size++; search = NULL; } free(valueDup); } else if (strcmp(key, "siteEnvPrepend") == 0) { char *valueDup = strdup(value); char *search = valueDup; char *svPtr = NULL; char *ptr = NULL; while ((ptr = strtok_r(search, " ", &svPtr)) != NULL) { char **siteEnvPrependPtr = config->siteEnvPrepend + config->siteEnvPrepend_size; strncpy_StringArray(ptr, strlen(ptr), &siteEnvPrependPtr, &(config->siteEnvPrepend), &(config->siteEnvPrepend_capacity), SITEFS_ALLOC_BLOCK); config->siteEnvPrepend_size++; search = NULL; } free(valueDup); } else if (strcmp(key, "imageGateway") == 0) { char *valueDup = strdup(value); char *search = valueDup; int ret = 0; char *svPtr = NULL; char *ptr = NULL; while ((ptr = strtok_r(search, " ", &svPtr)) != NULL) { char **gwUrlPtr = config->gwUrl + config->gwUrl_size; strncpy_StringArray(ptr, strlen(ptr), &(gwUrlPtr), &(config->gwUrl), &(config->gwUrl_capacity), SERVER_ALLOC_BLOCK); config->gwUrl_size++; search = NULL; } free(valueDup); return ret; } else if (strcmp(key, "batchType") == 0) { config->batchType = strdup(value); if (config->batchType == NULL) return 1; } else if (strcmp(key, "system") == 0) { config->system = strdup(value); if (config->system == NULL) return 1; } else if (strcmp(key, "defaultImageType") == 0) { config->defaultImageType = strdup(value); } else if (strcmp(key, "nodeContextPrefix") == 0) { /* do nothing, this key is defunct */ } else { printf("Couldn't understand key: %s\n", key); return 2; } return 0; }