(linenum→info "unix/slp.c:2238")

glibc/2.7/nscd/nscd_conf.c

    1: /* Copyright (c) 1998, 2000, 2003-2006, 2007 Free Software Foundation, Inc.
    2:    This file is part of the GNU C Library.
    3:    Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
    4: 
    5:    This program is free software; you can redistribute it and/or modify
    6:    it under the terms of the GNU General Public License as published
    7:    by the Free Software Foundation; version 2 of the License, or
    8:    (at your option) any later version.
    9: 
   10:    This program is distributed in the hope that it will be useful,
   11:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   12:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13:    GNU General Public License for more details.
   14: 
   15:    You should have received a copy of the GNU General Public License
   16:    along with this program; if not, write to the Free Software Foundation,
   17:    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
   18: 
   19: #include <ctype.h>
   20: #include <errno.h>
   21: #include <error.h>
   22: #include <libintl.h>
   23: #include <malloc.h>
   24: #include <pwd.h>
   25: #include <stdio.h>
   26: #include <stdio_ext.h>
   27: #include <stdlib.h>
   28: #include <string.h>
   29: #include <unistd.h>
   30: #include <sys/param.h>
   31: #include <sys/types.h>
   32: 
   33: #include "dbg_log.h"
   34: #include "nscd.h"
   35: 
   36: /* Wrapper functions with error checking for standard functions.  */
   37: extern char *xstrdup (const char *s);
   38: 
   39: 
   40: /* Names of the databases.  */
   41: const char *const dbnames[lastdb] =
   42: {
   43:   [pwddb] = "passwd",
   44:   [grpdb] = "group",
   45:   [hstdb] = "hosts",
   46:   [servdb] = "services"
   47: };
   48: 
   49: 
   50: static int
   51: find_db (const char *name)
   52: {
   53:   for (int cnt = 0; cnt < lastdb; ++cnt)
   54:     if (strcmp (name, dbnames[cnt]) == 0)
   55:       return cnt;
   56: 
   57:   error (0, 0, _("database %s is not supported"), name);
   58:   return -1;
   59: }
   60: 
   61: int
   62: nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
   63: {
   64:   FILE *fp;
   65:   char *line, *cp, *entry, *arg1, *arg2;
   66:   size_t len;
   67:   int cnt;
   68:   const unsigned int initial_error_message_count = error_message_count;
   69: 
   70:   /* Open the configuration file.  */
   71:   fp = fopen (fname, "r");
   72:   if (fp == NULL)
   73:     return -1;
   74: 
   75:   /* The stream is not used by more than one thread.  */
   76:   (void) __fsetlocking (fp, FSETLOCKING_BYCALLER);
   77: 
   78:   line = NULL;
   79:   len = 0;
   80: 
   81:   do
   82:     {
   83:       ssize_t n = getline (&line, &len, fp);
   84:       if (n < 0)
   85:         break;
   86:       if (line[n - 1] == '\n')
   87:         line[n - 1] = '\0';
   88: 
   89:       /* Because the file format does not know any form of quoting we
   90:          can search forward for the next '#' character and if found
   91:          make it terminating the line.  */
   92:       *strchrnul (line, '#') = '\0';
   93: 
   94:       /* If the line is blank it is ignored.  */
   95:       if (line[0] == '\0')
   96:         continue;
   97: 
   98:       entry = line;
   99:       while (isspace (*entry) && *entry != '\0')
  100:         ++entry;
  101:       cp = entry;
  102:       while (!isspace (*cp) && *cp != '\0')
  103:         ++cp;
  104:       arg1 = cp;
  105:       ++arg1;
  106:       *cp = '\0';
  107:       if (strlen (entry) == 0)
  108:         error (0, 0, _("Parse error: %s"), line);
  109:       while (isspace (*arg1) && *arg1 != '\0')
  110:         ++arg1;
  111:       cp = arg1;
  112:       while (!isspace (*cp) && *cp != '\0')
  113:         ++cp;
  114:       arg2 = cp;
  115:       ++arg2;
  116:       *cp = '\0';
  117:       if (strlen (arg2) > 0)
  118:         {
  119:           while (isspace (*arg2) && *arg2 != '\0')
  120:             ++arg2;
  121:           cp = arg2;
  122:           while (!isspace (*cp) && *cp != '\0')
  123:             ++cp;
  124:           *cp = '\0';
  125:         }
  126: 
  127:       if (strcmp (entry, "positive-time-to-live") == 0)
  128:         {
  129:           int idx = find_db (arg1);
  130:           if (idx >= 0)
  131:             dbs[idx].postimeout = atol (arg2);
  132:         }
  133:       else if (strcmp (entry, "negative-time-to-live") == 0)
  134:         {
  135:           int idx = find_db (arg1);
  136:           if (idx >= 0)
  137:             dbs[idx].negtimeout = atol (arg2);
  138:         }
  139:       else if (strcmp (entry, "suggested-size") == 0)
  140:         {
  141:           int idx = find_db (arg1);
  142:           if (idx >= 0)
  143:             dbs[idx].suggested_module = atol (arg2);
  144:         }
  145:       else if (strcmp (entry, "enable-cache") == 0)
  146:         {
  147:           int idx = find_db (arg1);
  148:           if (idx >= 0)
  149:             {
  150:               if (strcmp (arg2, "no") == 0)
  151:                 dbs[idx].enabled = 0;
  152:               else if (strcmp (arg2, "yes") == 0)
  153:                 dbs[idx].enabled = 1;
  154:             }
  155:         }
  156:       else if (strcmp (entry, "check-files") == 0)
  157:         {
  158:           int idx = find_db (arg1);
  159:           if (idx >= 0)
  160:             {
  161:               if (strcmp (arg2, "no") == 0)
  162:                 dbs[idx].check_file = 0;
  163:               else if (strcmp (arg2, "yes") == 0)
  164:                 dbs[idx].check_file = 1;
  165:             }
  166:         }
  167:       else if (strcmp (entry, "max-db-size") == 0)
  168:         {
  169:           int idx = find_db (arg1);
  170:           if (idx >= 0)
  171:             dbs[idx].max_db_size = atol (arg2);
  172:         }
  173:       else if (strcmp (entry, "logfile") == 0)
  174:         set_logfile (arg1);
  175:       else if (strcmp (entry, "debug-level") == 0)
  176:         {
  177:           int level = atoi (arg1);
  178:           if (level > 0)
  179:             debug_level = level;
  180:         }
  181:       else if (strcmp (entry, "threads") == 0)
  182:         {
  183:           if (nthreads == -1)
  184:             nthreads = MAX (atol (arg1), lastdb);
  185:         }
  186:       else if (strcmp (entry, "max-threads") == 0)
  187:         {
  188:           max_nthreads = MAX (atol (arg1), lastdb);
  189:         }
  190:       else if (strcmp (entry, "server-user") == 0)
  191:         {
  192:           if (!arg1)
  193:             error (0, 0, _("Must specify user name for server-user option"));
  194:           else
  195:             server_user = xstrdup (arg1);
  196:         }
  197:       else if (strcmp (entry, "stat-user") == 0)
  198:         {
  199:           if (arg1 == NULL)
  200:             error (0, 0, _("Must specify user name for stat-user option"));
  201:           else
  202:             {
  203:               stat_user = xstrdup (arg1);
  204: 
  205:               struct passwd *pw = getpwnam (stat_user);
  206:               if (pw != NULL)
  207:                 stat_uid = pw->pw_uid;
  208:             }
  209:         }
  210:       else if (strcmp (entry, "persistent") == 0)
  211:         {
  212:           int idx = find_db (arg1);
  213:           if (idx >= 0)
  214:             {
  215:               if (strcmp (arg2, "no") == 0)
  216:                 dbs[idx].persistent = 0;
  217:               else if (strcmp (arg2, "yes") == 0)
  218:                 dbs[idx].persistent = 1;
  219:             }
  220:         }
  221:       else if (strcmp (entry, "shared") == 0)
  222:         {
  223:           int idx = find_db (arg1);
  224:           if (idx >= 0)
  225:             {
  226:               if (strcmp (arg2, "no") == 0)
  227:                 dbs[idx].shared = 0;
  228:               else if (strcmp (arg2, "yes") == 0)
  229:                 dbs[idx].shared = 1;
  230:             }
  231:         }
  232:       else if (strcmp (entry, "reload-count") == 0)
  233:         {
  234:           if (strcasecmp (arg1, "unlimited") == 0)
  235:             reload_count = UINT_MAX;
  236:           else
  237:             {
  238:               unsigned int count = strtoul (arg1, NULL, 0);
  239:               if (count > UINT8_MAX - 1)
  240:                 reload_count = UINT_MAX;
  241:               else if (count >= 0)
  242:             reload_count = count;
  243:               else
  244:                 error (0, 0, _("invalid value for 'reload-count': %u"), count);
  245:             }
  246:         }
  247:       else if (strcmp (entry, "paranoia") == 0)
  248:         {
  249:           if (strcmp (arg1, "no") == 0)
  250:             paranoia = 0;
  251:           else if (strcmp (arg1, "yes") == 0)
  252:             paranoia = 1;
  253:         }
  254:       else if (strcmp (entry, "restart-interval") == 0)
  255:         {
  256:           if (arg1 != NULL)
  257:             restart_interval = atol (arg1);
  258:           else
  259:             error (0, 0, _("Must specify value for restart-interval option"));
  260:         }
  261:       else if (strcmp (entry, "auto-propagate") == 0)
  262:         {
  263:           int idx = find_db (arg1);
  264:           if (idx >= 0)
  265:             {
  266:               if (strcmp (arg2, "no") == 0)
  267:                 dbs[idx].propagate = 0;
  268:               else if (strcmp (arg2, "yes") == 0)
  269:                 dbs[idx].propagate = 1;
  270:             }
  271:         }
  272:       else
  273:         error (0, 0, _("Unknown option: %s %s %s"), entry, arg1, arg2);
  274:     }
  275:   while (!feof_unlocked (fp));
  276: 
  277:   if (paranoia)
  278:     {
  279:       restart_time = time (NULL) + restart_interval;
  280: 
  281:       /* Save the old current workding directory if we are in paranoia
  282:          mode.  We have to change back to it.  */
  283:       oldcwd = get_current_dir_name ();
  284:       if (oldcwd == NULL)
  285:         {
  286:           error (0, 0, _("\
  287: cannot get current working directory: %s; disabling paranoia mode"),
  288:                    strerror (errno));
  289:           paranoia = 0;
  290:         }
  291:     }
  292: 
  293:   /* Enforce sanity.  */
  294:   if (max_nthreads < nthreads)
  295:     max_nthreads = nthreads;
  296: 
  297:   for (cnt = 0; cnt < lastdb; ++cnt)
  298:     {
  299:       size_t datasize = (sizeof (struct database_pers_head)
  300:                          + roundup (dbs[cnt].suggested_module
  301:                                     * sizeof (ref_t), ALIGN)
  302:                          + (dbs[cnt].suggested_module
  303:                             * DEFAULT_DATASIZE_PER_BUCKET));
  304:       if (datasize > dbs[cnt].max_db_size)
  305:         {
  306:           error (0, 0, _("maximum file size for %s database too small"),
  307:                    dbnames[cnt]);
  308:           dbs[cnt].max_db_size = datasize;
  309:         }
  310: 
  311:     }
  312: 
  313:   /* Free the buffer.  */
  314:   free (line);
  315:   /* Close configuration file.  */
  316:   fclose (fp);
  317: 
  318:   return error_message_count != initial_error_message_count;
  319: }
Syntax (Markdown)