Logo Search packages:      
Sourcecode: bandwidthd version File versions  Download package

extensions.c

#include "bandwidthd.h"
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

extern struct config config;

static char *execute_extension(char * filename);

struct extensions *execute_extensions(void)
      {
    struct dirent **namelist;
    int Counter, n;
      struct stat statbuffer;
      char *filename;   
      struct extensions *results = NULL;
      struct extensions **resptr;
      char *ptr;

      resptr = &results;

    n = scandir(EXTENSION_DIR, &namelist, 0, alphasort);
    if (n < 0)
            syslog(LOG_ERR, "Failed to open %s for executing extensions", EXTENSION_DIR);
    else 
            {
      for(Counter = 0; Counter < n; Counter++) 
                  {
                  filename = malloc(strlen(EXTENSION_DIR)+strlen(namelist[Counter]->d_name)+2);
                  sprintf(filename, "%s/%s", EXTENSION_DIR, namelist[Counter]->d_name);
                  stat(filename, &statbuffer);
                  
                  if (S_ISREG(statbuffer.st_mode))
                        {
                        ptr = execute_extension(filename);
                        if (ptr)
                              {
                              *resptr = malloc(sizeof(struct extensions));
                              (*resptr)->name = strdup(namelist[Counter]->d_name);
                              (*resptr)->value = ptr;             
                              (*resptr)->next = NULL;
                              resptr = &((*resptr)->next);
                              }
                        }
                  free(filename);
            free(namelist[Counter]);
            }
        free(namelist);
        }

      return(results);
      }

static char *execute_extension(char *filename)
      {
      int ExtPipe[2];
      pid_t extpid;
      char buffer[1500];
      char *res = NULL;
      char *ptr;
      ssize_t len;
      int child;
      int Counter;

      fd_set rset;
      fd_set eset;

    if (pipe(ExtPipe))
        {
        syslog(LOG_ERR, "Failed to open pipe for extension processing");
        return(NULL);
        }

      if (!(extpid = fork()))
            {
            close(ExtPipe[0]);
            dup2(ExtPipe[1], 1);

        execl(filename, filename, config.dev, NULL);
        syslog(LOG_ERR, "Failed to launch extension %s", filename);
        _exit(1);
            }

      close(ExtPipe[1]);
      
      child = 1;
      while (child)
            {
            child = !waitpid(extpid, NULL, WNOHANG);
      
            // If child is running drop into a select and wait for data
            if (child)
                  {
                  FD_ZERO(&rset);
                  FD_SET(ExtPipe[0], &rset);
                  FD_ZERO(&eset);
                  FD_SET(ExtPipe[0], &eset);
                  
                  select(ExtPipe[0]+1, &rset, NULL, &eset, NULL);
                  }
            
            len = 1;
            while (len)
                  {
                  len = read(ExtPipe[0], buffer, 1499);  
                  buffer[len] = '\0';

                  if (res)
                        {
                        ptr = malloc(strlen(res)+len+1);
                        sprintf(ptr, "%s%s", res, buffer);
                        free(res);
                        }
                  else
                        {
                        ptr = malloc(len+1);
                        sprintf(ptr, "%s", buffer);
                        }
                  res = ptr;
                  }
            }
      close(ExtPipe[0]);

      // Trim whitespace from end
      for(Counter = strlen(res)-1; Counter >= 0; Counter--)
            {
            if (res[Counter] == ' ' || res[Counter] == '\t' || res[Counter] == '\r' || res[Counter] == '\n')
                  res[Counter] = '\0';
            else
                  break;
            }

      // Filter empty responses (Also filters all whitespace responses because of previouse trim)
      if (strlen(res) < 1)
            {
            free(res);
            return(NULL);
            }
      else
            return(res);
      }

void destroy_extension_data(struct extensions *ext)
      {
      struct extensions *ptr;
      struct extensions *ptr2;
      ptr = ext;
      while(ptr)
            {
            if (ptr->name) 
                  free(ptr->name);
            if (ptr->value)
                  free(ptr->value);
            ptr2 = ptr->next;
            free(ptr);
            ptr = ptr2;
            }
      }

/*
int main(void)
      {
      struct extensions *res;
      struct extensions *resptr;

      res = execute_extensions();
      resptr = res;

      while(resptr)
            {
            printf("%s\n", resptr->name);
            printf("%s\n", resptr->value);
            resptr = resptr->next;
            }

      destroy_extensions(res);
      return(0);
      }

*/

Generated by  Doxygen 1.6.0   Back to index