[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/clayne/patchdiff2/master/unix_fct.cpp [Back]  [Original]

/*
   Patchdiff2
   Portions (C) 2010 Nicolas Pouvesle
   Portions (C) 2007 - 2009 Tenable Network Security, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License version 2 as
   published by the Free Software Foundation.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see .
*/

#include 
#include 
#include 
#include 

#define USE_DANGEROUS_FUNCTIONS

#include 
#include 

#include "unix_fct.h"
#include "system.h"

struct ipc_data {
   int spipe;
   int rpipe;
   char *sname;
   char *rname;
   pid_t pid;
};

typedef struct ipc_data ipc_data_t;

/*------------------------------------------------*/
/* function : create_process                      */
/* description: fork/exec                         */
/*------------------------------------------------*/

pid_t create_process(char *cmd) {
   pid_t pid;
   char *argv[4];

   pid = fork();
   if (pid == 0) {
      // Assume execvp is safe to call with const char strings
      argv[0] = const_cast("/bin/sh");
      argv[1] = const_cast("-c");
      argv[2] = cmd;
      argv[3] = NULL;

      execvp(argv[0], argv);
      exit(EXIT_FAILURE);
   }

   return pid;
}

/*------------------------------------------------*/
/* function : os_execute_command                  */
/* description: Executes a command by creating a  */
/*              new process                       */
/*------------------------------------------------*/

int os_execute_command(char *cmd, bool close, void *data) {
   ipc_data_t *id = (ipc_data_t *)data;
   int ret = -1;
   int status;
   pid_t pid;

   pid = create_process(cmd);
   if (pid == -1) {
      return -1;
   }
   if (close) {
      /* we wait until the process finished (IE: sig file is generated) */
      if (waitpid(pid, &status, 0) == -1) {
         return -1;
      }
   }
   else {
      id->pid = pid;
   }

   return 0;
}

/*------------------------------------------------*/
/* function : os_check_process                    */
/* description: checks process state              */
/*------------------------------------------------*/

bool os_check_process(pid_t pid) {
   if (kill(pid, 0) == 0) {
      return true;
   }
   return false;
}

/*------------------------------------------------*/
/* function : os_copy_to_clipboard                */
/* description: Copies data to clipboard          */
/*------------------------------------------------*/

void os_copy_to_clipboard(char *data) {
}

/*------------------------------------------------*/
/* function : os_get_pid                          */
/* description: Returns process ID                */
/*------------------------------------------------*/

long os_get_pid() {
   return (long)getpid();
}

/*------------------------------------------------*/
/* function : os_unlink                           */
/* description: removes a link to a file          */
/*------------------------------------------------*/

int os_unlink(const char *path) {
   return unlink(path);
}

/*------------------------------------------------*/
/* function : os_tempnam                          */
/* description: returns a temporary file name     */
/*------------------------------------------------*/

void os_tempnam(char *data, size_t size, const char *suffix) {
   char *str = strdup(P_tmpdir "/patchdiff2-XXXXXX");;

   // TODO: Just use mkstemp and don't mind the lack of extension
   int fd = mkstemp(str);
   close(fd);
   unlink(str);
   qsnprintf(data, size, "%s%s", str, suffix);
   free(str);
}

/*------------------------------------------------*/
/* function : os_ipc_send                         */
/* description: Sends data on pipe                */
/*------------------------------------------------*/

bool os_ipc_send(void *data, int type, idata_t *d) {
   ipc_data_t *id = (ipc_data_t *)data;
   ssize_t num;

   num = write(id->spipe, d, sizeof(*d));
   if (num > 0) {
      return true;
   }
   return false;
}

/*------------------------------------------------*/
/* function : os_ipc_recv                         */
/* description: Receives data on pipe             */
/*------------------------------------------------*/

bool os_ipc_recv(void *data, int type, idata_t *d) {
   ipc_data_t *id = (ipc_data_t *)data;
   fd_set rfds, efds;
   struct timeval tv;
   int ret;

   tv.tv_sec = 0;
   tv.tv_usec = 1000;

   if (id->pid) {
      while (1) {
         FD_ZERO(&rfds);
         FD_SET(id->rpipe, &rfds);

         FD_ZERO(&efds);
         FD_SET(id->rpipe, &efds);

         ret = select(id->rpipe + 1, &rfds, NULL, &efds, &tv);
         if (ret > 0 && FD_ISSET(id->rpipe, &rfds)) {
            break;
         }
         if (ret < 0 || (ret > 0 && FD_ISSET(id->rpipe, &efds)) || !os_check_process(id->pid)) {
            return false;
         }
      }
   }
   else {
       FD_ZERO(&rfds);
       FD_SET(id->rpipe, &rfds);

       FD_ZERO(&efds);
       FD_SET(id->rpipe, &efds);

       ret = select(id->rpipe + 1, &rfds, NULL, &efds, NULL);
       if (!(ret > 0 && FD_ISSET(id->rpipe, &rfds))) {
          return false;
         }
   }

   read(id->rpipe, d, sizeof(*d));

   return true;
}

/*------------------------------------------------*/
/* function : os_ipc_init                         */
/* description: Inits interprocess communication  */
/*------------------------------------------------*/

bool os_ipc_init(void ** data, long pid, int type) {
   char sname[512];
   char rname[512];
   ipc_data_t *id;

   id = new ipc_data_t();
   if (!id) {
      return false;
   }
   memset(id, '\0', sizeof(*id));

   qsnprintf(sname, sizeof(sname), "/tmp/pdiff2spipe%ld", pid);
   qsnprintf(rname, sizeof(rname), "/tmp/pdiff2rpipe%ld", pid);

   id->sname = qstrdup(sname);
   id->rname = qstrdup(rname);

   if (type == IPC_SERVER) {
      mkfifo(sname, 0666);
      id->spipe = open(sname, O_RDWR|O_NONBLOCK);
      if (id->spipe == -1) {
         goto error;
      }
      mkfifo(rname, 0666);
      id->rpipe = open(rname, O_RDWR|O_NONBLOCK);
      if (id->rpipe == -1) {
         goto error;
      }
   }
   else {
      id->spipe = open(rname, O_WRONLY);
      if (id->spipe == -1) {
         goto error;
      }
      id->rpipe = open(sname, O_RDONLY);
      if (id->rpipe == -1) {
         goto error;
      }
   }

   *data = (void *)id;
   return true;

error:
   if (id->spipe) {
      close(id->spipe);
   }
   if (id->rpipe) {
      close(id->rpipe);
   }
   delete id;
   return false;
}

/*------------------------------------------------*/
/* function : os_ipc_close                        */
/* description: Closes IPC                        */
/*------------------------------------------------*/

bool os_ipc_close(void *data) {
   ipc_data_t *id = (ipc_data_t *)data;

   if (id->spipe) {
      close(id->spipe);
   }
   if (id->rpipe) {
      close(id->rpipe);
   }
   os_unlink(id->sname);
   os_unlink(id->rname);
   return true;
}

/*------------------------------------------------*/
/* function : os_get_pref_int                     */
/* description: Gets system preferences (integer) */
/*------------------------------------------------*/

bool os_get_pref_int(const char *name, int *i) {
  *i = 0;
  return false;
}

Web Proxy Viewer  |  New URL  |  Original Page