// Copyright (C)2018, Philip Munts, President, Munts AM Corp. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. #include #include #include #include #include #include #define DELIMITERS " =\t\r\n" static FILE *f = NULL; // Open the configuration file void spiagent_config_open(int32_t *error) { assert(error != NULL); *error = 0; // See if the configuration file is already open if (f != NULL) return; // Open the configuration file f = fopen(CONFIGFILE, "r"); if (f == NULL) *error = errno; } // Close the configuration file void spiagent_config_close(int32_t *error) { assert(error != NULL); *error = 0; // See if the configuration file is already closed if (f == NULL) return; // Close the configuration file if (fclose(f)) *error = errno; f = NULL; } // Get the next keyword from the configuration file void spiagent_config_get_next(char *keyword, int32_t ksize, char *value, int32_t vsize, int32_t *error) { assert(error != NULL); // Validate parameters if (keyword == NULL) { *error = EINVAL; return; } if (ksize < 32) { *error = EINVAL; return; } if (value == NULL) { *error = EINVAL; return; } if (vsize < 256) { *error = EINVAL; return; } char inbuf[1024]; char *k; char *v; // See if the configuration file is open if (f == NULL) { *error = EBADF; return; } // Search for the next keyword/value pair memset(keyword, 0, ksize); memset(value, 0, vsize); while (fgets(inbuf, sizeof(inbuf), f) != NULL) { k = strtok(inbuf, DELIMITERS); if (k == NULL) continue; // Blank line if (k[0] == '#') continue; // Comment if (k[0] == ';') continue; // Comment v = strtok(NULL, DELIMITERS); if (v == NULL) continue; // Malformed strncpy(keyword, k, ksize - 1); strncpy(value, v, vsize - 1); *error = 0; return; } *error = ENODATA; } void spiagent_config_get(char *keyword, char *value, int32_t vsize, int32_t *error) { assert(error != NULL); // Validate parameters if (keyword == NULL) { *error = EINVAL; return; } if (value == NULL) { *error = EINVAL; return; } if (vsize < 256) { *error = EINVAL; return; } char k[256]; char v[256]; // See if the configuration file is open if (f == NULL) { *error = EBADF; return; } // Rewind the configuration file rewind(f); // Search for the desired keyword for (;;) { spiagent_config_get_next(k, sizeof(k), v, sizeof(v), error); if (*error) return; if (!strcasecmp(keyword, k)) { memset(value, 0, vsize); strncpy(value, v, vsize - 1); *error = 0; return; } } *error = ENODATA; }