"Fossies" - the Fresh Open Source Software Archive

Member "fusesmb-0.8.7/configfile.c" (4 May 2006, 12338 Bytes) of package /linux/privat/old/fusesmb-0.8.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "configfile.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * The MIT License
    3  *
    4  * Copyright (c) 2006 Vincent Wagelaar
    5  *
    6  * Permission is hereby granted, free of charge, to any person obtaining a
    7  * copy of this software and associated documentation files (the
    8  * "Software"), to deal in the Software without restriction, including
    9  * without limitation the rights to use, copy, modify, merge, publish,
   10  * distribute, sublicense, and/or sell copies of the Software, and to
   11  * permit persons to whom the Software is furnished to do so, subject to
   12  * the following conditions:
   13  *
   14  * The above copyright notice and this permission notice shall be included
   15  * in all copies or substantial portions of the Software.
   16  *
   17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   20  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   21  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   24  */
   25 
   26 #include <stdio.h>
   27 #include <string.h>
   28 #include <sys/param.h>
   29 #include "stringlist.h"
   30 #include <sys/types.h>
   31 #include <sys/stat.h>
   32 #include <unistd.h>
   33 #include <ctype.h>
   34 #include "configfile.h"
   35 
   36 
   37 static char *strip_whitespace_check_comment(const char *str)
   38 {
   39     char *start = (char *)str;
   40     char *end = start + strlen(str) -1;
   41     while (*start == '\t' || *start == ' ')
   42         start++;
   43     while (isspace(*end))
   44     {
   45         *end = '\0';
   46         end--;
   47     }
   48     if (*start == '#' || *start == ';' || *start == '\0')
   49         return NULL;
   50     return start;
   51 }
   52 
   53 static char *strip_whitespace(const char *str)
   54 {
   55     char *start = (char *)str;
   56     char *end = start + strlen(str) -1;
   57     while (*start == '\t' || *start == ' ')
   58         start++;
   59     while (isspace(*end))
   60     {
   61         *end = '\0';
   62         end--;
   63     }
   64     if (*start == '\0')
   65         return NULL;
   66     return start;
   67 }
   68 
   69 static int config_read_file(config_t *cf)
   70 {
   71     char buf[4096];
   72     FILE *fp = fopen(cf->file, "r");
   73     if (NULL == fp)
   74         return -1;
   75     sl_clear(cf->lines);
   76     while (!feof(fp))
   77     {
   78         if (NULL == fgets(buf, sizeof(buf), fp))
   79             continue;
   80         char *stripped_string = strip_whitespace_check_comment(buf);
   81         if (stripped_string == NULL)
   82             continue;
   83         /* Section */
   84         if (*stripped_string == '[')
   85         {
   86             stripped_string++;
   87             while (*stripped_string == '\t' || *stripped_string == ' ')
   88             {
   89                 stripped_string++;
   90             }
   91             char *end = stripped_string + strlen(stripped_string) -1;
   92             while (*end == '\t' || *end == ' ' || *end == ']')
   93             {
   94                 *end = '\0';
   95                 end--;
   96             }
   97             char section_string[4096];
   98             snprintf(section_string, sizeof(section_string), "[%s]", stripped_string);
   99             if (-1 == sl_add(cf->lines, section_string, 1))
  100                 continue;
  101         } /* Key */
  102         else
  103         {
  104 
  105             char value_string[4096];
  106             char *isequal = index(stripped_string, '=');
  107             if (isequal == NULL)
  108                 continue;
  109             *isequal = '\0';
  110             isequal++;
  111             char *key = strip_whitespace(stripped_string);
  112             char *value = strip_whitespace(isequal);
  113             if (NULL == key || NULL == value)
  114                 continue;
  115             snprintf(value_string, sizeof(value_string), "%s=%s", key, value);
  116             if (-1 == sl_add(cf->lines, value_string, 1))
  117                 continue;
  118         }
  119     }
  120     fclose(fp);
  121     return 0;
  122 }
  123 
  124 
  125 /**
  126  * Init configuration interface
  127  * @return -1 on failure, 0 on success
  128  */
  129 int config_init(config_t *cf, const char *file)
  130 {
  131     struct stat st;
  132     if (-1 == stat(file, &st))
  133         return -1;
  134     cf->mtime = st.st_mtime;
  135     cf->lines = sl_init();
  136     if (cf->lines == NULL)
  137         return -1;
  138     strncpy(cf->file, file, MAXPATHLEN);
  139     config_read_file(cf);
  140     return 0;
  141 }
  142 
  143 /**
  144  * @param config_t *, pointer to config_t
  145  * @return -1 if not needed/failure, 0 file has changed
  146  */
  147 
  148 int config_reload_ifneeded(config_t *cf)
  149 {
  150     struct stat st;
  151     if (-1 == stat(cf->file, &st))
  152         return -1;
  153     if (cf->mtime == st.st_mtime)
  154         return -1;
  155     cf->mtime = st.st_mtime;
  156     return config_read_file(cf);
  157 }
  158 /**
  159  * @return -1 on failure, 0 on success
  160  */
  161 int config_has_section(config_t *cf, const char *section)
  162 {
  163     char buf[strlen(section)+3];
  164     strcpy(buf, "[");
  165     strcat(buf, section);
  166     strcat(buf, "]");
  167     if (NULL != sl_find(cf->lines, buf))
  168     {
  169         return 0;
  170     }
  171     return -1;
  172 }
  173 
  174 /**
  175  * @return -1 on failure, 0 on success with value now with a malloced string
  176  */
  177 int config_read_string(config_t *cf, const char *section, const char *key, char **value)
  178 {
  179     size_t i;
  180     char cmp_section[strlen(section)+3];
  181     char cmp_key[strlen(key)+2];
  182     strcpy(cmp_section, "[");
  183     strcat(cmp_section, section);
  184     strcat(cmp_section, "]");
  185     strcpy(cmp_key, key);
  186     strcat(cmp_key, "=");
  187     char section_found = 0;
  188     for (i=0; i<sl_count(cf->lines); i++)
  189     {
  190         if (0 == strncasecmp(sl_item(cf->lines, i), cmp_section, sizeof(cmp_section))
  191             && section_found == 0)
  192         {
  193             section_found = 1;
  194             i++;
  195         }
  196         /* Check if we're not over the last line */
  197         if (section_found == 1 && i < sl_count(cf->lines))
  198         {
  199             if (0 == strncasecmp(sl_item(cf->lines, i), "[", 1))
  200             {
  201                 return -1;
  202             }
  203             if (0 == strncasecmp(sl_item(cf->lines, i), cmp_key, strlen(cmp_key)))
  204             {
  205                 char *retval = index(sl_item(cf->lines, i), '=');
  206                 if (retval == NULL)
  207                     return -1;
  208                 retval++;
  209                 if (strlen(retval))
  210                 {
  211                     *value = strdup(retval);
  212                     return 0;
  213                 }
  214                 return -1;
  215             }
  216         }
  217     }
  218     return -1;
  219 }
  220 
  221 /**
  222  * @return -1 on failure, 0 on success
  223  */
  224 int config_read_int(config_t *cf, const char *section, const char *key, int *value)
  225 {
  226     char *str;
  227     if (0 == config_read_string(cf, section, key, &str))
  228     {
  229         char *p;
  230         int ret = strtol(str, &p, 10);
  231         if (*p != '\0')
  232             return -1;
  233         *value = ret;
  234         free(str);
  235         return 0;
  236     }
  237     return -1;
  238 }
  239 
  240 /**
  241  * @return -1 on failure, 0 on success
  242  */
  243 int config_read_bool(config_t *cf, const char *section, const char *key, int *value)
  244 {
  245     char *str;
  246     if (0 == config_read_string(cf, section, key, &str))
  247     {
  248         if (strcasecmp("true", str) == 0 || strcmp("1", str) == 0)
  249         {
  250             *value = 1;
  251             free(str);
  252             return 0;
  253         }
  254         if (strcasecmp("false", str) == 0 || strcmp("0", str) == 0)
  255         {
  256             *value = 0;
  257             free(str);
  258             return 0;
  259         }
  260         free(str);
  261     }
  262     return -1;
  263 }
  264 
  265 int config_read_stringlist(config_t *cf, const char *section, const char *key, stringlist_t **value, char sep)
  266 {
  267     char *str;
  268     if (0 == config_read_string(cf, section, key, &str))
  269     {
  270         *value = sl_init();
  271         char *next, *start;
  272         start = str;
  273         while (NULL != (next = index(start, sep)))
  274         {
  275             *next = '\0';
  276             next++;
  277             /* Remove extra separators */
  278             while (*next == sep)
  279             {
  280                 *next = '\0';
  281                 next++;
  282             }
  283             char *stripped;
  284             if (NULL != (stripped = strip_whitespace(start)))
  285                 sl_add(*value, stripped, 1);
  286 
  287             start = next;
  288         }
  289         if (strlen(start))
  290         {
  291             char *stripped = strip_whitespace(start);
  292             sl_add(*value, stripped, 1);
  293         }
  294         free(str);
  295         return 0;
  296     }
  297     return -1;
  298 }
  299 int config_read_section_keys(config_t *cf, const char *section, stringlist_t **value)
  300 {
  301     size_t i;
  302     char cmp_section[strlen(section)+3];
  303     strcpy(cmp_section, "[");
  304     strcat(cmp_section, section);
  305     strcat(cmp_section, "]");
  306     char section_found = 0;
  307     *value = sl_init();
  308     if (NULL == *value)
  309         return -1;
  310 
  311     for (i=0; i<sl_count(cf->lines); i++)
  312     {
  313         if (0 == strncasecmp(sl_item(cf->lines, i), cmp_section, sizeof(cmp_section))
  314             && section_found == 0)
  315         {
  316             section_found = 1;
  317             i++;
  318         }
  319         if (section_found == 1)
  320         {
  321             if (0 == strncasecmp(sl_item(cf->lines, i), "[", 1))
  322             {
  323                 break;
  324             }
  325             char buf[4096];
  326             strncpy(buf, sl_item(cf->lines, i), 4096);
  327             char *sep = index(buf, '=');
  328             if (sep == NULL)
  329                 continue;
  330             *sep = '\0';
  331             if (strlen(buf))
  332             {
  333                 if (-1 == sl_add(*value, buf, 1))
  334                     continue;
  335             }
  336         }
  337     }
  338     if (sl_count(*value) > 0)
  339         return 0;
  340 
  341     /* No keys found for this sections so freeing up the stringlist */
  342     sl_free(*value);
  343     *value = NULL;
  344     return -1;
  345 }
  346 
  347 void config_free(config_t *cf)
  348 {
  349     sl_free(cf->lines);
  350 }
  351 
  352 #ifdef RUN_TEST
  353 
  354 static void config_show_parsed(config_t *cf)
  355 {
  356     size_t i;
  357     for (i=0; i<sl_count(cf->lines); i++)
  358     {
  359         printf("%s\n", sl_item(cf->lines, i));
  360     }
  361 }
  362 
  363 
  364 int keeprunning =1;
  365 
  366 #include <signal.h>
  367 #include <errno.h>
  368 void int_handler(int sig)
  369 {
  370     signal(sig, SIG_IGN);
  371     printf("CTRL_C pressed\n");
  372     keeprunning =0;
  373 }
  374 
  375 int main(void)
  376 {
  377     signal(SIGINT, int_handler);
  378     config_t c;
  379     if (-1 == config_init(&c, "fusesmb.conf.test"))
  380     {
  381         perror("config_init");
  382         //fprintf(stderr, "Could not open fusesmb.conf [%s]\n", strerror(errno));
  383         exit(EXIT_FAILURE);
  384     }
  385     config_show_parsed(&c);
  386     while(keeprunning){
  387     char *user, *pass;
  388     stringlist_t *workgroups, *servers;
  389 
  390     int timeout, showhiddenshares;
  391     if (0 == config_read_string(&c, "global", "username", &user))
  392     {
  393         printf("Found username: %s\n", user);
  394         free(user);
  395     }
  396     else
  397         printf("Could not find username\n");
  398 
  399     if (0 == config_read_string(&c, "global", "password", &pass))
  400     {
  401         printf("Found password: %s\n", pass);
  402         free(pass);
  403     }
  404     else
  405         printf("Could not find password\n");
  406     if (0 == config_reload_ifneeded(&c))
  407         printf("Configuration has changed\n");
  408     if (0 == config_read_int(&c, "global", "timeout", &timeout))
  409         printf("Found timeout: %i\n", timeout);
  410     else
  411         printf("Could not find timeout\n");
  412     if (0 == config_read_bool(&c, "global", "showhiddenshares", &showhiddenshares))
  413         printf("Found showhiddenshares: %i\n", showhiddenshares);
  414     else
  415         printf("Could not find showhiddenshares\n");
  416 
  417     if (0 == config_read_stringlist(&c, "ignore", "workgroups", &workgroups, ','))
  418     {
  419         size_t i;
  420         printf("Found workgroups:\n");
  421         for (i=0; i<sl_count(workgroups); i++)
  422             printf(" %s\n", sl_item(workgroups, i));
  423         sl_free(workgroups);
  424     }
  425     else
  426     {
  427         printf("Could not find ignore workgroups\n");
  428     }
  429     if (0 == config_read_stringlist(&c, "ignore", "servers", &servers, ','))
  430     {
  431         size_t i;
  432         printf("Found servers:\n");
  433         sl_casesort(servers);
  434         for (i=0; i<sl_count(servers); i++)
  435             printf(" %s\n", sl_item(servers, i));
  436         char *find;
  437         if (NULL != (find = sl_casefind(servers, "TARdis")))
  438             printf("Found TARdis: %s\n", find);
  439         if (NULL != (find = sl_casefind(servers, "BANANA")))
  440             printf("Found TARdis: %s\n", find);
  441 
  442         sl_free(servers);
  443     }
  444     else
  445     {
  446         printf("Could not find ignore servers\n");
  447     }
  448     stringlist_t *global_keys;
  449     if (0 == config_read_section_keys(&c, "global", &global_keys))
  450     {
  451         size_t i;
  452         for (i=0; i<sl_count(global_keys); i++)
  453             printf("key: %s\n", sl_item(global_keys, i));
  454         sl_free(global_keys);
  455     }
  456     sleep(10);
  457     }
  458     printf("Cleaning up\n");
  459     config_show_parsed(&c);
  460     config_free(&c);
  461     exit(EXIT_SUCCESS);
  462 }
  463 #endif