/* This has functions to read the configuration file */
/* ------------------------------------------------- */

#include "headers.h" /* has all important stuff */

/* reads configure file.. etc. */
void config()
{
#  if !defined(SUN) && !defined(BSD)
   int res1;
#  endif

   int dosend = 0;

   char *res; 
   char buf[MAXREADSIZE/4];

   if (confd != NULL)
   {
      register int i;

      (void)fclose(confd);

      if (debugging == 1)
      {
         (void)putchar('\n');
         (void)write(dblogfd, "\n", 1);
      }

      debug("got request to re-HUP config file\n\n");

      for (i = 0; i <= curlogfd; i++) 
      {
          if ((logs[i].fd <= 0) && (logs[i].filename == NULL)) continue;
          else
          {
             if (logs[i].fd > 0) close(logs[i].fd);
             if (logs[i].filename != NULL) free(logs[i].filename);

             memset(&logs[i], 0, sizeof(struct log));

             logs[i].fd = ERROR;
             logs[i].filename = NULL;
          }
      }

      if ((connected == 1) && (gotInfoServ == 1)) dosend = 1;
   }

# if !defined(SUN) && !defined(BSD)
#  ifdef _POSIX_SAVED_IDS
   res1 = setuid(0);
#  else
   res1 = seteuid(0);
#  endif

   if (res1 == ERROR)
   {
      error("error setting [e]uid: %s\n\n", strerror(errno));
      quit(ERROR);
   }
# endif

   confd = fopen(CONFILE, "r");
   if (confd == NULL)
   {
      error("error opening %s: %s\n\n", CONFILE, strerror(errno));
      quit(ERROR);
   }
    
   curlogfd = ERROR;

   while(1)
   {      
      memset(buf, 0, sizeof(buf));

      res = fgets(buf, sizeof(buf)-1, confd);
      if (res == NULL)
      {
         if (errno == EINTR) continue;
         else if ((!feof(confd)) && (errno > 0))
         {
            error("error reading from %s: %s\n\n", CONFILE, strerror(errno));
            quit(ERROR);
         }

         else
         {
            /* (void)fclose(confd); */ /* may need to re-HUP later on */
            break;
         }
      }    

      if (isprint((int)buf[0]) == 0) continue;
      else
      {
         debug("parsing line:\n%s\n", buf);
         parseSysConf(buf);          
      }
   }

#  if !defined(SUN) && !defined(BSD)
   if (pwd != NULL)
   {
#     ifdef _POSIX_SAVED_IDS
      res1 = setuid(pwd->pw_uid);
#     else
      res1 = seteuid(pwd->pw_uid);
#     endif

      if (res1 == ERROR)
      {
         error("error setting [e]uid: %s\n\n", strerror(errno));
         quit(ERROR);
      }
   }
#  endif

   printConfig();

   if (dosend == 1)
   {
      debug("now re-sending syslog.conf to server\n");
      sendSysConf();
   }
}


/* -------------------------------- */


/* output what's being logged where */
void printConfig()
{
   register int i;

   debug("current files being logged to:\n");

   for (i = 0; i <= curlogfd; i++)
   {
       if ((logs[i].filename == NULL) || (logs[i].fd <= 0)) continue;

       if ((logs[i].facility != ALL) && 
           (logs[i].priority.priority != ALL)  &&
           (logs[i].priority.priority != NONE))
       {
          debug("%s, for %s.%s\n", logs[i].filename,
                facValToName(logs[i].facility),
                priValToName(logs[i].priority.priority));

       }
 
       else
       {
          if (logs[i].facility == ALL)
          {
             if (logs[i].priority.priority == ALL)
                debug("%s, for *.*\n", logs[i].filename);

             else if (logs[i].priority.priority == NONE)
                debug("%s, for *.none\n", logs[i].filename);

             else
                debug("%s, for *.%s\n", logs[i].filename, 
                      priValToName(logs[i].priority.priority));
          }

          else if (logs[i].priority.priority == ALL)
             debug("%s, for %s.*\n", logs[i].filename,
                   facValToName(logs[i].facility));

          else if (logs[i].priority.priority == NONE)
             debug("%s, for %s.none\n", logs[i].filename,
                   facValToName(logs[i].facility));
       }
   }

   if (debugging == 1)
   {
      (void)putchar('\n');
      (void)write(dblogfd, "\n", 1);
   }
}


/* -------------------------------- */


/* send syslog.conf to server */
void sendSysConf()
{
   int res;
   char *res1;
   char buf[MAXREADSIZE];

   send_data("START SYSLOG.CONF\n");

   /* FIX - add timeout */
   while(1)
   {
      memset(buf, 0, sizeof(buf));
      recv_data(buf, sizeof(buf));

      if (strncmp(buf, "START SYSLOG.CONF OKAY", 22) == 0)
      {
         debug("got server's permissions to start sending\n\n");
         break;
      }
   }

/* (should already be open)
   confd = fopen(CONFILE, "r");
   if (confd == NULL)
   {
      error("error opening %s: %s\n\n", CONFILE, strerror(errno));
      quit(ERROR);
   }
*/
    
   res = fseek(confd, 0, SEEK_SET);
   if (res == ERROR)
   {
      error("error with fseek(): %s\n\n", strerror(errno));
      quit(ERROR);
   }

   while(1)
   {      
      memset(buf, 0, sizeof(buf));

      res1 = fgets(buf, sizeof(buf)-1, confd);
      if (res1 == NULL)
      {
         if (errno == EINTR) continue;
         else if ((!feof(confd)) && (errno > 0))
         {
            error("error reading from %s: %s\n\n", CONFILE, strerror(errno));
            quit(ERROR);
         }

         else 
         {
            /* (void)fclose(confd); */ /* may need to re-HUP later on */
            break;
         }
      }    

      if (isprint((int)buf[0]) == 0) continue;
      else send_data(buf);
   }

   send_data("END SYSLOG.CONF\n");

   /* FIX - add timeout */
   while(1)
   {
      memset(buf, 0, sizeof(buf));
      recv_data(buf, sizeof(buf));

      if (strncmp(buf, "SUCCESSFUL logging", 18) == 0)
      {
         (void)printf("syslog.conf was sent successfully\n\n");
         break;
      }
   }
}
