Ejemplo n.º 1
0
/* open a config file and separate it into lines for read_config_line() */
static void read_config_file(const fnchar *filename)
{
    FILE *fp;
    int fsize;
    char *buf, *line;
    
    fp = fopen(filename, "rb");
    if (!fp)
	return;

    /* obtain file size. */
    fseek(fp , 0 , SEEK_END);
    fsize = ftell(fp);
    rewind(fp);
    
    if (!fsize) {/* truncated config file */
	fclose(fp);
	return;
    }

    buf = malloc(fsize+1);
    if (!buf) {
	fclose(fp);
	return;
    }

    fread(buf, fsize, 1, fp);
    fclose(fp);
    
    buf[fsize] = '\0';
    
    /* each option is expected to have the following format:
	* name=value\n
	*/
    line = strtok(buf, "\n");
    do {
	read_config_line(line);
	
	line = strtok(NULL, "\n");
    } while (line);
    
    free(buf);
}
Ejemplo n.º 2
0
/* open a config file and separate it into lines for read_config_line() */
static void
read_config_file(const fnchar * filename)
{
    FILE *fp;
    int fsize;
    char *line;

    fp = fopen(filename, "rb");
    if (!fp)
        return;

    /* obtain file size. */
    fseek(fp, 0, SEEK_END);
    fsize = ftell(fp);
    rewind(fp);

    if (!fsize) {       /* truncated config file */
        fclose(fp);
        return;
    }

    char buf[fsize + 1];

    if (fread(buf, 1, fsize, fp) < fsize) {
        /* This can only happen if the file shrinks while it's open; let's just
           not read the file at all, because it's probably corrupted */
        curses_msgwin("warning: corrupted configuration file",
                      krc_notification);
        fclose(fp);
        return;
    }
    fclose(fp);

    buf[fsize] = '\0';

    /* each option is expected to have the following format: * name=value\n */
    line = strtok(buf, "\n");
    do {
        read_config_line(line);

        line = strtok(NULL, "\n");
    } while (line);
}
Ejemplo n.º 3
0
int parse_configfile(const char *filename, configfile_value_fn fn)
{
	static int nesting;
	int len;
	char line[512];
	const char *value;
	FILE *f;

	/* cancel deeply nested include-commands */
	if (nesting > 8)
		return -1;
	if (!(f = fopen(filename, "r")))
		return -1;
	nesting++;
	while((len = read_config_line(f, line, &value, sizeof(line))) > 0)
		fn(line, value);
	nesting--;
	fclose(f);
	return 0;
}
Ejemplo n.º 4
0
/*
 * Returns -1 on (fatal) error,
 *         0 on success.
 */
static int read_config_file
(
   struct relabsd_config * const conf,
   char * const filename
)
{
   FILE * f;
   char buffer[(RELABSD_CONF_AXIS_CODE_SIZE + 1)];
   int continue_reading, prev_errno;

   buffer[RELABSD_CONF_AXIS_CODE_SIZE] = '\0';

   f = fopen(filename, "r");

   if (f == (FILE *) NULL)
   {
      RELABSD_FATAL
      (
         "[CONFIG] Could not open file: %s.",
         strerror(errno)
      );

      return -1;
   }

   prev_errno = errno;
   errno = 0;

   continue_reading = 1;

   while
   (
      (continue_reading == 1)
      &&
      (
         fscanf
         (
            f,
            "%" RELABSD_TO_STRING(RELABSD_CONF_AXIS_CODE_SIZE) "s",
            buffer
         )
         != EOF
      )
   )
   {
      switch (read_config_line(conf, f, buffer))
      {
         case 1:
            /* Everything is going well. */
            break;

         case 0:
            /* EOF reached. */
            continue_reading = 0;
            break;

         case -1:
            /* A fatal error occured. */
            errno = prev_errno;

            fclose(f);
            return -1;
      }
   }

   if (errno != 0)
   {
      /* An error happened in the while loop condition. */
      RELABSD_FATAL
      (
         "[CONFIG] Error while reading file: %s, last read '%s'.",
         strerror(errno),
         buffer
      );

      errno = prev_errno;

      fclose(f);

      return -1;
   }

   errno = prev_errno;

   fclose(f);

   return 0;
}
Ejemplo n.º 5
0
Archivo: loaders.c Proyecto: mfb/orbot
/*********************************************************************
 *
 * Function    :  load_one_re_filterfile
 *
 * Description :  Load a re_filterfile. 
 *                Generate a chained list of re_filterfile_spec's from
 *                the "FILTER: " blocks, compiling all their substitutions
 *                into chained lists of pcrs_job structs.
 *
 * Parameters  :
 *          1  :  csp = Current client state (buffers, headers, etc...)
 *
 * Returns     :  0 => Ok, everything else is an error.
 *
 *********************************************************************/
int load_one_re_filterfile(struct client_state *csp, int fileid)
{
   FILE *fp;

   struct re_filterfile_spec *new_bl, *bl = NULL;
   struct file_list *fs;

   char  buf[BUFFER_SIZE];
   int error;
   unsigned long linenum = 0;
   pcrs_job *dummy, *lastjob = NULL;

   /*
    * No need to reload if unchanged
    */
   if (!check_file_changed(current_re_filterfile[fileid], csp->config->re_filterfile[fileid], &fs))
   {
      if (csp)
      {
         csp->rlist[fileid] = current_re_filterfile[fileid];
      }
      return(0);
   }
   if (!fs)
   {
      goto load_re_filterfile_error;
   }

   /* 
    * Open the file or fail
    */
   if ((fp = fopen(csp->config->re_filterfile[fileid], "r")) == NULL)
   {
      goto load_re_filterfile_error;
   }

   /* 
    * Read line by line
    */
   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
   {
      int new_filter = NO_NEW_FILTER;

      if (strncmp(buf, "FILTER:", 7) == 0)
      {
         new_filter = FT_CONTENT_FILTER;
      }
      else if (strncmp(buf, "SERVER-HEADER-FILTER:", 21) == 0)
      {
         new_filter = FT_SERVER_HEADER_FILTER;
      }
      else if (strncmp(buf, "CLIENT-HEADER-FILTER:", 21) == 0)
      {
         new_filter = FT_CLIENT_HEADER_FILTER;
      }
      else if (strncmp(buf, "CLIENT-HEADER-TAGGER:", 21) == 0)
      {
         new_filter = FT_CLIENT_HEADER_TAGGER;
      }
      else if (strncmp(buf, "SERVER-HEADER-TAGGER:", 21) == 0)
      {
         new_filter = FT_SERVER_HEADER_TAGGER;
      }

      /*
       * If this is the head of a new filter block, make it a
       * re_filterfile spec of its own and chain it to the list:
       */
      if (new_filter != NO_NEW_FILTER)
      {
         new_bl = (struct re_filterfile_spec  *)zalloc(sizeof(*bl));
         if (new_bl == NULL)
         {
            goto load_re_filterfile_error;
         }
         if (new_filter == FT_CONTENT_FILTER)
         {
            new_bl->name = chomp(buf + 7);
         }
         else
         {
            new_bl->name = chomp(buf + 21);
         }
         new_bl->type = new_filter;

         /*
          * If a filter description is available,
          * encode it to HTML and save it.
          */
         if (NULL != (new_bl->description = strpbrk(new_bl->name, " \t")))
         {
            *new_bl->description++ = '\0';
            new_bl->description = html_encode(chomp(new_bl->description));
            if (NULL == new_bl->description)
            {
               new_bl->description = strdup("Out of memory while encoding this filter's description to HTML");
            }
         }
         else
         {
            new_bl->description = strdup("No description available for this filter");
         }

         new_bl->name = strdup(chomp(new_bl->name));
         
         /*
          * If this is the first filter block, chain it
          * to the file_list rather than its (nonexistant)
          * predecessor
          */
         if (fs->f == NULL)
         {
            fs->f = new_bl;
         }
         else
         {
            assert(NULL != bl);
            bl->next = new_bl;
         }
         bl = new_bl;

         log_error(LOG_LEVEL_RE_FILTER, "Reading in filter \"%s\" (\"%s\")", bl->name, bl->description);

         continue;
      }

      /* 
       * Else, save the expression, make it a pcrs_job
       * and chain it into the current filter's joblist 
       */
      if (bl != NULL)
      {
         error = enlist(bl->patterns, buf);
         if (JB_ERR_MEMORY == error)
         {
            log_error(LOG_LEVEL_FATAL,
               "Out of memory while enlisting re_filter job \'%s\' for filter %s.", buf, bl->name);
         }
         assert(JB_ERR_OK == error);

         if (pcrs_job_is_dynamic(buf))
         {
            /*
             * Dynamic pattern that might contain variables
             * and has to be recompiled for every request
             */
            if (bl->joblist != NULL)
            {
                pcrs_free_joblist(bl->joblist);
                bl->joblist = NULL;
            }
            bl->dynamic = 1;
            log_error(LOG_LEVEL_RE_FILTER,
               "Adding dynamic re_filter job \'%s\' to filter %s succeeded.", buf, bl->name);
            continue;             
         }
         else if (bl->dynamic)
         {
            /*
             * A previous job was dynamic and as we
             * recompile the whole filter anyway, it
             * makes no sense to compile this job now.
             */
            log_error(LOG_LEVEL_RE_FILTER,
               "Adding static re_filter job \'%s\' to dynamic filter %s succeeded.", buf, bl->name);
            continue;
         }

         if ((dummy = pcrs_compile_command(buf, &error)) == NULL)
         {
            log_error(LOG_LEVEL_ERROR,
               "Adding re_filter job \'%s\' to filter %s failed with error %d.", buf, bl->name, error);
            continue;
         }
         else
         {
            if (bl->joblist == NULL)
            {
               bl->joblist = dummy;
            }
            else if (NULL != lastjob)
            {
               lastjob->next = dummy;
            }
            lastjob = dummy;
            log_error(LOG_LEVEL_RE_FILTER, "Adding re_filter job \'%s\' to filter %s succeeded.", buf, bl->name);
         }
      }
      else
      {
         log_error(LOG_LEVEL_ERROR, "Ignoring job %s outside filter block in %s, line %d",
            buf, csp->config->re_filterfile[fileid], linenum);
      }
   }

   fclose(fp);

   /* 
    * Schedule the now-obsolete old data for unloading
    */
   if ( NULL != current_re_filterfile[fileid] )
   {
      current_re_filterfile[fileid]->unloader = unload_re_filterfile;
   }

   /*
    * Chain this file into the global list of loaded files
    */
   fs->next    = files->next;
   files->next = fs;
   current_re_filterfile[fileid] = fs;

   if (csp)
   {
      csp->rlist[fileid] = fs;
   }

   return( 0 );

load_re_filterfile_error:
   log_error(LOG_LEVEL_FATAL, "can't load re_filterfile '%s': %E",
             csp->config->re_filterfile[fileid]);
   return(-1);

}
Ejemplo n.º 6
0
Archivo: loaders.c Proyecto: mfb/orbot
/*********************************************************************
 *
 * Function    :  load_trustfile
 *
 * Description :  Read and parse a trustfile and add to files list.
 *
 * Parameters  :
 *          1  :  csp = Current client state (buffers, headers, etc...)
 *
 * Returns     :  0 => Ok, everything else is an error.
 *
 *********************************************************************/
int load_trustfile(struct client_state *csp)
{
   FILE *fp;

   struct block_spec *b, *bl;
   struct url_spec **tl;

   char  buf[BUFFER_SIZE], *p, *q;
   int reject, trusted;
   struct file_list *fs;
   unsigned long linenum = 0;
   int trusted_referrers = 0;

   if (!check_file_changed(current_trustfile, csp->config->trustfile, &fs))
   {
      /* No need to load */
      if (csp)
      {
         csp->tlist = current_trustfile;
      }
      return(0);
   }
   if (!fs)
   {
      goto load_trustfile_error;
   }

   fs->f = bl = (struct block_spec *)zalloc(sizeof(*bl));
   if (bl == NULL)
   {
      goto load_trustfile_error;
   }

   if ((fp = fopen(csp->config->trustfile, "r")) == NULL)
   {
      goto load_trustfile_error;
   }

   tl = csp->config->trust_list;

   while (read_config_line(buf, sizeof(buf), fp, &linenum) != NULL)
   {
      trusted = 0;
      reject  = 1;

      if (*buf == '+')
      {
         trusted = 1;
         *buf = '~';
      }

      if (*buf == '~')
      {
         reject = 0;
         p = buf;
         q = p+1;
         while ((*p++ = *q++) != '\0')
         {
            /* nop */
         }
      }

      /* skip blank lines */
      if (*buf == '\0')
      {
         continue;
      }

      /* allocate a new node */
      if ((b = zalloc(sizeof(*b))) == NULL)
      {
         fclose(fp);
         goto load_trustfile_error;
      }

      /* add it to the list */
      b->next  = bl->next;
      bl->next = b;

      b->reject = reject;

      /* Save the URL pattern */
      if (create_url_spec(b->url, buf))
      {
         fclose(fp);
         goto load_trustfile_error;
      }

      /*
       * save a pointer to URL's spec in the list of trusted URL's, too
       */
      if (trusted)
      {
         if(++trusted_referrers < MAX_TRUSTED_REFERRERS)
         {
            *tl++ = b->url;
         }
      }
   }

   if(trusted_referrers >= MAX_TRUSTED_REFERRERS) 
   {
      /*
       * FIXME: ... after Privoxy 3.0.4 is out.
       */
       log_error(LOG_LEVEL_ERROR, "Too many trusted referrers. Current limit is %d, you are using %d.\n"
          "  Additional trusted referrers are treated like ordinary trusted URLs.\n"
          "  (You can increase this limit by changing MAX_TRUSTED_REFERRERS in project.h and recompiling).",
          MAX_TRUSTED_REFERRERS, trusted_referrers);
   }

   *tl = NULL;

   fclose(fp);

   /* the old one is now obsolete */
   if (current_trustfile)
   {
      current_trustfile->unloader = unload_trustfile;
   }

   fs->next    = files->next;
   files->next = fs;
   current_trustfile = fs;

   if (csp)
   {
      csp->tlist = fs;
   }

   return(0);

load_trustfile_error:
   log_error(LOG_LEVEL_FATAL, "can't load trustfile '%s': %E",
             csp->config->trustfile);
   return(-1);

}