コード例 #1
0
ファイル: util_funcs.c プロジェクト: OPSF/uClinux
RETSIGTYPE
restart_doit(int a)
{
    char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
                                        NETSNMP_DS_LIB_APPTYPE);
    snmp_shutdown(name);

    /*  This signal handler may run with SIGALARM blocked.
     *  Since the signal mask is preserved accross execv(), we must 
     *  make sure that SIGALARM is unblocked prior of execv'ing.
     *  Otherwise SIGALARM will be ignored in the next incarnation
     *  of snmpd, because the signal is blocked. And thus, the 
     *  restart doesn't work anymore. 
     */ 
#if HAVE_SIGBLOCK 
    sigsetmask(0);
#endif 

    /*
     * do the exec 
     */
#if HAVE_EXECV
    execv(argvrestartname, argvrestartp);
    setPerrorstatus(argvrestartname);
#endif
}
コード例 #2
0
ファイル: util_funcs.c プロジェクト: OPSF/uClinux
void
wait_on_exec(struct extensible *ex)
{
#if defined(WIN32) && !defined (mingw32)
  int rc;
  if (ex->tid != 0 && ex->pid != 0) {
    HANDLE hThread = (HANDLE) ex->tid;
    HANDLE hProcess = (HANDLE) ex->pid;
    rc = WaitForSingleObject(hProcess, NETSNMP_TIMEOUT_WAITFORSINGLEOBJECT);
    DEBUGMSGT(("exec:wait_on_exec","WaitForSingleObject rc=(%d)\n",rc ));
    rc = CloseHandle( hThread );
    DEBUGMSGT(("exec:wait_on_exec","CloseHandle hThread=(%d)\n",rc ));
    rc = CloseHandle( hProcess );
    DEBUGMSGT(("exec:wait_on_exec","CloseHandle hProcess=(%d)\n",rc ));
    ex->pid = 0;
    ex->tid = 0;
  }
#else
#ifndef NETSNMP_EXCACHETIME
    if (ex->pid && waitpid(ex->pid, &ex->result, 0) < 0) {
        setPerrorstatus("waitpid");
    }
    ex->pid = 0;
#endif  /* NETSNMP_EXCACHETIME */
#endif  /* WIN32 */
}
コード例 #3
0
ファイル: regexp_proc.c プロジェクト: ClydeFroq/sipxecs
int
sh_count_regexp_procs(char *procname, pcre *regexp)
{
    char            line[STRMAX], *cptr, *cp;
    int             ret = 0, fd;
    FILE           *file;
#ifndef NETSNMP_EXCACHETIME
#endif
    struct extensible ex;
    int             slow = strstr(PSCMD, "ax") != NULL;

    strcpy(ex.command, PSCMD);
    if ((fd = get_exec_output(&ex)) >= 0) {
        if ((file = fdopen(fd, "r")) == NULL) {
            setPerrorstatus("fdopen");
            close(fd);
            return (-1);
        }
        while (fgets(line, sizeof(line), file) != NULL) {
            if (slow) {
                cptr = find_field(line, 5);
                cp = strrchr(cptr, '/');
                if (cp)
                    cptr = cp + 1;
                else if (*cptr == '-')
                    cptr++;
                else if (*cptr == '[') {
                    cptr++;
                    cp = strchr(cptr, ']');
                    if (cp)
                        *cp = 0;
                }
                copy_nword(cptr, line, sizeof(line));
                cp = line + strlen(line) - 1;
                if (*cp == ':')
                    *cp = 0;
            } else {
                if ((cptr = find_field(line, NETSNMP_LASTFIELD)) == NULL)
                    continue;
                copy_nword(cptr, line, sizeof(line));
            }
            if (!strcmp(line, procname))
                ret++;
        }
        if (ftell(file) < 2) {
#ifdef USING_UCD_SNMP_ERRORMIB_MODULE
            seterrorstatus("process list unreasonable short (mem?)", 2);
#endif
            ret = -1;
        }
        fclose(file);
        wait_on_exec(&ex);
    } else {
        ret = -1;
    }
    return (ret);
}
コード例 #4
0
ファイル: util_funcs.c プロジェクト: AllardJ/Tomato
void
wait_on_exec(struct extensible *ex)
{
#ifndef EXCACHETIME
    if (ex->pid && waitpid(ex->pid, &ex->result, 0) < 0) {
        setPerrorstatus("waitpid");
    }
    ex->pid = 0;
#endif
}
コード例 #5
0
ファイル: restart.cpp プロジェクト: duniansampa/SigLog
RETSIGTYPE
restart_doit(int a)
{
    char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
                                        NETSNMP_DS_LIB_APPTYPE);
    snmp_shutdown(name);

    /*  This signal handler may run with SIGALARM blocked.
     *  Since the signal mask is preserved accross execv(), we must
     *  make sure that SIGALARM is unblocked prior of execv'ing.
     *  Otherwise SIGALARM will be ignored in the next incarnation
     *  of snmpd, because the signal is blocked. And thus, the
     *  restart doesn't work anymore.
     *
     *  A quote from the sigprocmask() man page:
     *  The use of sigprocmask() is unspecified in a multithreaded process; see
     *  pthread_sigmask(3).
     */
#if HAVE_SIGPROCMASK
    {
        sigset_t empty_set;

        sigemptyset(&empty_set);
        sigprocmask(SIG_SETMASK, &empty_set, NULL);
    }
#elif HAVE_SIGBLOCK
    sigsetmask(0);
#endif

    /*
     * do the exec
     */
#if HAVE_EXECV
    execv(argvrestartname, argvrestartp);
    setPerrorstatus(argvrestartname);
#endif
}
コード例 #6
0
ファイル: util_funcs.c プロジェクト: AllardJ/Tomato
int
get_exec_output(struct extensible *ex)
{
#if HAVE_EXECV
    int             fd[2], i, cnt;
    char            ctmp[STRMAX], *cptr1, *cptr2, argvs[STRMAX], **argv,
        **aptr;
#ifdef EXCACHETIME
    char            cachefile[STRMAX];
    char            cache[MAXCACHESIZE];
    ssize_t         cachebytes;
    long            curtime;
    static char     lastcmd[STRMAX];
    int             cfd;
    static int      lastresult;
    int             readcount;
#endif

#ifdef EXCACHETIME
    sprintf(cachefile, "%s/%s", get_persistent_directory(), CACHEFILE);
    curtime = time(NULL);
    if (curtime > (cachetime + EXCACHETIME) ||
        strcmp(ex->command, lastcmd) != 0) {
        strcpy(lastcmd, ex->command);
        cachetime = curtime;
#endif
        if (pipe(fd)) {
            setPerrorstatus("pipe");
#ifdef EXCACHETIME
            cachetime = 0;
#endif
            return -1;
        }
        if ((ex->pid = fork()) == 0) {
            close(1);
            if (dup(fd[1]) != 1) {
                setPerrorstatus("dup");
                return -1;
            }

            /*
             * write standard output and standard error to pipe. 
             */
            /*
             * close all other file descriptors. 
             */
            for (cnt = getdtablesize() - 1; cnt >= 2; --cnt)
                (void) close(cnt);
            (void) dup(1);      /* stderr */

            /*
             * set standard input to /dev/null 
             */
            close(0);
            (void) open("/dev/null", O_RDWR);

            for (cnt = 1, cptr1 = ex->command, cptr2 = argvs;
                 cptr1 && *cptr1 != 0; cptr2++, cptr1++) {
                *cptr2 = *cptr1;
                if (*cptr1 == ' ') {
                    *(cptr2++) = 0;
                    if ((cptr1 = skip_white(cptr1)) == NULL)
                        break;
                    if (cptr1) {
                        *cptr2 = *cptr1;
                        if (*cptr1 != 0)
                            cnt++;
                    }
                }
            }
            *cptr2 = 0;
            *(cptr2 + 1) = 0;
            argv = (char **) malloc((cnt + 2) * sizeof(char *));
            if (argv == NULL)
                return 0;       /* memory alloc error */
            aptr = argv;
            *(aptr++) = argvs;
            for (cptr2 = argvs, i = 1; i != cnt; cptr2++)
                if (*cptr2 == 0) {
                    *(aptr++) = cptr2 + 1;
                    i++;
                }
            while (*cptr2 != 0)
                cptr2++;
            *(aptr++) = NULL;
            copy_nword(ex->command, ctmp, sizeof(ctmp));
            execv(ctmp, argv);
            perror(ctmp);
            exit(1);
        } else {
            close(fd[1]);
            if (ex->pid < 0) {
                close(fd[0]);
                setPerrorstatus("fork");
#ifdef EXCACHETIME
                cachetime = 0;
#endif
                return -1;
            }
#ifdef EXCACHETIME
            unlink(cachefile);
            /*
             * XXX  Use SNMP_FILEMODE_CLOSED instead of 644? 
             */
            if ((cfd =
                 open(cachefile, O_WRONLY | O_TRUNC | O_CREAT,
                      0644)) < 0) {
                setPerrorstatus(cachefile);
                cachetime = 0;
                return -1;
            }
            fcntl(fd[0], F_SETFL, O_NONBLOCK);  /* don't block on reads */
#ifdef HAVE_USLEEP
            for (readcount = 0; readcount <= MAXREADCOUNT * 100 &&
                 (cachebytes = read(fd[0], (void *) cache, MAXCACHESIZE));
                 readcount++) {
#else
            for (readcount = 0; readcount <= MAXREADCOUNT &&
                 (cachebytes = read(fd[0], (void *) cache, MAXCACHESIZE));
                 readcount++) {
#endif
                if (cachebytes > 0)
                    write(cfd, (void *) cache, cachebytes);
                else if (cachebytes == -1 && errno != EAGAIN) {
                    setPerrorstatus("read");
                    break;
                } else
#ifdef HAVE_USLEEP
                    usleep(10000);      /* sleeps for 0.01 sec */
#else
                    sleep(1);
#endif
            }
            close(cfd);
            close(fd[0]);
            /*
             * wait for the child to finish 
             */
            if (ex->pid > 0 && waitpid(ex->pid, &ex->result, 0) < 0) {
                setPerrorstatus("waitpid()");
                cachetime = 0;
                return -1;
            }
            ex->pid = 0;
            ex->result = WEXITSTATUS(ex->result);
            lastresult = ex->result;
#else                           /* !EXCACHETIME */
            return (fd[0]);
#endif
        }
#ifdef EXCACHETIME
    } else {
コード例 #7
0
ファイル: execute.cpp プロジェクト: duniansampa/SigLog
int
run_exec_command( char *command, char *input,
                  char *output,  int  *out_len)	/* Or realloc style ? */
{
#if HAVE_EXECV
    int ipipe[2];
    int opipe[2];
    int i;
    int pid;
    int result;
    char **argv;
    int argc;

    DEBUGMSGTL(("run:exec", "running '%s'\n", command));
    pipe(ipipe);
    pipe(opipe);
    if ((pid = fork()) == 0) {
        /*
         * Child process
         */

        /*
         * Set stdin/out/err to use the pipe
         *   and close everything else
         */
        close(0);
        dup(  ipipe[0]);
	close(ipipe[1]);

        close(1);
        dup(  opipe[1]);
        close(opipe[0]);
        close(2);
        dup(1);
        for (i = getdtablesize()-1; i>2; i--)
            close(i);

        /*
         * Set up the argv array and execute it
         * This is being run in the child process,
         *   so will release resources when it terminates.
         */
        argv = tokenize_exec_command( command, &argc );
        execv( argv[0], argv );
        perror( argv[0] );
        exit(1);	/* End of child */

    } else if (pid > 0) {
        char            cache[NETSNMP_MAXCACHESIZE];
        char           *cache_ptr;
        ssize_t         count, cache_size, offset = 0;
        int             waited = 0, numfds;
        fd_set          readfds;
        struct timeval  timeout;

        /*
         * Parent process
         */

        /*
	 * Pass the input message (if any) to the child,
         * wait for the child to finish executing, and read
         *    any output into the output buffer (if provided)
         */
	close(ipipe[0]);
	close(opipe[1]);
	if (input) {
	   write(ipipe[1], input, strlen(input));
	   close(ipipe[1]);	/* or flush? */
        }
	else close(ipipe[1]);

        /*
         * child will block if it writes a lot of data and
         * fills up the pipe before exiting, so we read data
         * to keep the pipe empty.
         */
        if (output && ((NULL == out_len) || (0 == *out_len))) {
            DEBUGMSGTL(("run:exec",
                        "invalid params; no output will be returned\n"));
            output = NULL;
        }
        if (output) {
            cache_ptr = output;
            cache_size = *out_len - 1;
        } else {
            cache_ptr = cache;
            cache_size = sizeof(cache);
        }

        /*
         * xxx: some of this code was lifted from get_exec_output
         * in util_funcs.c. Probably should be moved to a common
         * routine for both to use.
         */
        DEBUGMSGTL(("verbose:run:exec","  waiting for child %d...\n", pid));
        numfds = opipe[0] + 1;
        i = NETSNMP_MAXREADCOUNT;
        for (; i; --i) {
            /*
             * set up data for select
             */
            FD_ZERO(&readfds);
            FD_SET(opipe[0],&readfds);
            timeout.tv_sec = 1;
            timeout.tv_usec = 0;

            DEBUGMSGTL(("verbose:run:exec", "    calling select\n"));
            count = select(numfds, &readfds, NULL, NULL, &timeout);
            if (count == -1) {
                if (EAGAIN == errno)
                    continue;
                else {
                    DEBUGMSGTL(("verbose:run:exec", "      errno %d\n",
                                errno));
                    setPerrorstatus("read");
                    break;
                }
            } else if (0 == count) {
                DEBUGMSGTL(("verbose:run:exec", "      timeout\n"));
                continue;
            }

            if (! FD_ISSET(opipe[0], &readfds)) {
                DEBUGMSGTL(("verbose:run:exec", "    fd not ready!\n"));
                continue;
            }

            /*
             * read data from the pipe, optionally saving to output buffer
             */
            count = read(opipe[0], &cache_ptr[offset], cache_size);
            DEBUGMSGTL(("verbose:run:exec",
                        "    read %d bytes\n", (int)count));
            if (0 == count) {
                int rc;
                /*
                 * we shouldn't get no data, because select should
                 * wait til the fd is ready. before we go back around,
                 * check to see if the child exited.
                 */
                DEBUGMSGTL(("verbose:run:exec", "    no data!\n"));
                if ((rc = waitpid(pid, &result, WNOHANG)) <= 0) {
                    if (rc < 0) {
                        snmp_log_perror("waitpid");
                        break;
                    } else
                        DEBUGMSGTL(("verbose:run:exec",
                                    "      child not done!?!\n"));;
                } else {
                    DEBUGMSGTL(("verbose:run:exec", "      child done\n"));
                    waited = 1; /* don't wait again */
                    break;
                }
            }
            else if (count > 0) {
                /*
                 * got some data. fix up offset, if needed.
                 */
                if(output) {
                    offset += count;
                    cache_size -= count;
                    if (cache_size <= 0) {
                        DEBUGMSGTL(("verbose:run:exec",
                                    "      output full\n"));
                        break;
                    }
                    DEBUGMSGTL(("verbose:run:exec",
                                "    %d left in buffer\n", (int)cache_size));
                }
            }
            else if ((count == -1) && (EAGAIN != errno)) {
                /*
                 * if error, break
                 */
                DEBUGMSGTL(("verbose:run:exec", "      errno %d\n",
                            errno));
                setPerrorstatus("read");
                break;
            }
        }
        DEBUGMSGTL(("verbose:run:exec", "  done reading\n"));
        if (output)
            DEBUGMSGTL(("run:exec", "  got %d bytes\n", *out_len));
            
        /*
         * close pipe to signal that we aren't listenting any more.
         */
        close(opipe[0]);

        /*
         * if we didn't wait successfully above, wait now.
         * xxx-rks: seems like this is a waste of the agent's
         * time. maybe start a time to wait(WNOHANG) once a second,
         * and late the agent continue?
         */
        if ((!waited) && (waitpid(pid, &result, 0) < 0 )) {
            snmp_log_perror("waitpid");
            return -1;
        }

        /*
         * null terminate any output
         */
        if (output) {
	    output[offset] = 0;
	    *out_len = offset;
        }
        DEBUGMSGTL(("run:exec","  child %d finished. result=%d\n",
                    pid,result));

	return WEXITSTATUS(result);

    } else {
        /*
         * Parent process - fork failed
         */
        snmp_log_perror("fork");
	close(ipipe[0]);
	close(ipipe[1]);
	close(opipe[0]);
	close(opipe[1]);
	return -1;
    }
    
#else
    /*
     * If necessary, fall back to using 'system'
     */
    DEBUGMSGTL(("run:exec", "running shell command '%s'\n", command));
    return run_shell_command( command, input, output, out_len );
#endif
}
コード例 #8
0
ファイル: util_funcs.c プロジェクト: OPSF/uClinux
int
get_exec_pipes(char *cmd, int *fdIn, int *fdOut, int *pid)
{
/* 	Alexander Prömel, [email protected] 08/24/2006
	The following code, is tested on picotux rev. 1.01.
	I think, it will be better to put the named pipes, into /var/run or make it selectable via CONFIG file.
	If the pipe file already exist, the creation will fail.
	I put the pipes into /flash, the pipepath has to change in ucd-snmp/pass_persist.c too, if you change it here.
*/
#if HAVE_EXECV
#ifdef __uClinux__ /* HAVE uClinux */
	int in,out;
	char fifo_in_path[256];
	char fifo_out_path[256];
	pid_t tpid;
        
    if ((tpid = vfork()) == 0) { /*temp child*/
        execve(cmd, NULL,NULL);
        perror(cmd);
        exit(1);
    } else { 
		if(tpid > 0) {
			/*initialize workspace*/
			snprintf(fifo_in_path, 256, "/flash/cp_%d", tpid);
			snprintf(fifo_out_path, 256, "/flash/pc_%d", tpid);

			in = mkfifo(fifo_in_path, S_IRWXU);	/*Create Input Pipe, 700*/
			if ( in ) {
				perror("parent: inpipe");
				exit(0);
			}
			out = mkfifo(fifo_out_path, S_IRWXU);	/*Create Output Pipe, 700*/
			if ( out ) {
				perror("parent: outpipe");
				exit(0);
			}
						
			in = open(fifo_in_path,O_RDONLY);	/*open the Input Pipe read Only*/
			if(in < 0) {
				perror("parent: input");
				exit(0);
			}
			out = open(fifo_out_path,O_WRONLY); 	/*open the Output Pipe write Only*/
			if(out < 0) {
				perror("parent: output");
				exit(0);
			}
			
			*fdIn = in;	/*read*/
			*fdOut = out;	/*write*/
			*pid = tpid;	
			return (1);     /* We are returning 0 for error... */
		} else { /*pid < 0*/
			setPerrorstatus("vfork");
			return 0;
		}

    }
#else /*HAVE x86*/
    int             fd[2][2], i, cnt;
    char            ctmp[STRMAX], *cptr1, *cptr2, argvs[STRMAX], **argv,
        **aptr;
    /*
     * Setup our pipes 
     */
    if (pipe(fd[0]) || pipe(fd[1])) {
        setPerrorstatus("pipe");
        return 0;
    }
    if ((*pid = fork()) == 0) { /* First handle for the child */
        close(0);
        if (dup(fd[0][0]) != 0) {
            setPerrorstatus("dup 0");
            return 0;
        }
        close(1);
        if (dup(fd[1][1]) != 1) {
            setPerrorstatus("dup 1");
            return 0;
        }

        /*
         * write standard output and standard error to pipe. 
         */
        /*
         * close all non-standard open file descriptors 
         */
        for (cnt = getdtablesize() - 1; cnt >= 2; --cnt)
            (void) close(cnt);
        (void) dup(1);          /* stderr */

        for (cnt = 1, cptr1 = cmd, cptr2 = argvs; *cptr1 != 0;
             cptr2++, cptr1++) {
            *cptr2 = *cptr1;
            if (*cptr1 == ' ') {
                *(cptr2++) = 0;
                if ((cptr1 = skip_white(cptr1)) == NULL)
                    break;
                *cptr2 = *cptr1;
                if (*cptr1 != 0)
                    cnt++;
            }
        }
        *cptr2 = 0;
        *(cptr2 + 1) = 0;
        argv = (char **) malloc((cnt + 2) * sizeof(char *));
        if (argv == NULL)
            return 0;           /* memory alloc error */
        aptr = argv;
        *(aptr++) = argvs;
        for (cptr2 = argvs, i = 1; i != cnt; cptr2++)
            if (*cptr2 == 0) {
                *(aptr++) = cptr2 + 1;
                i++;
            }
        while (*cptr2 != 0)
            cptr2++;
        *(aptr++) = NULL;
        copy_nword(cmd, ctmp, sizeof(ctmp));
        execv(ctmp, argv);
        perror(ctmp);
        exit(1);
    } else {
        close(fd[0][0]);
        close(fd[1][1]);
        if (*pid < 0) {
            close(fd[0][1]);
            close(fd[1][0]);
            setPerrorstatus("fork");
            return 0;
        }
        *fdIn = fd[1][0];
        *fdOut = fd[0][1];
        return (1);             /* We are returning 0 for error... */
    }
#endif				/* uClinux or x86 */
#endif                          /* !HAVE_EXECV */
#if defined(WIN32) && !defined (mingw32) && !defined(HAVE_EXECV)
/* MSVC (MinGW not working but should use this code).  Cygwin already works as it has execv and fork */
    /* Reference:  MS tech note: 190351 */
    HANDLE hInputWriteTmp, hInputRead, hInputWrite = NULL;
    HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL;
        
    HANDLE hErrorWrite;
    SECURITY_ATTRIBUTES sa;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    
    sa.nLength= sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */    
    if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes CreatePipe ChildOut: %d\n",
            GetLastError()));
      return 0;
    }
    /* Child temporary input pipe with Inheritance on (sa.bInheritHandle is true) */    
    if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes CreatePipe ChildIn: %d\n", GetLastError()));
      return 0;
    }
    
    /* Copy the stdout handle to the stderr handle in case the child closes one of 
     * its stdout handles. */
    if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite, GetCurrentProcess(),
          &hErrorWrite,0, TRUE,DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes DuplicateHandle: %d\n", GetLastError()));
      return 0;
    }

    /* Create new copies of the input and output handles but set bInheritHandle to 
     * FALSE so the new handle can not be inherited.  Otherwise the handles can not
     * be closed.  */
    if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(),
          &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes DupliateHandle ChildOut: %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      return 0;
    }   
    if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
          GetCurrentProcess(), &hInputWrite, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs","get_exec_pipes DupliateHandle ChildIn: %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      return 0;
    }

    /* Close the temporary output and input handles */
    if (!CloseHandle(hOutputReadTmp)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes CloseHandle (hOutputReadTmp): %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      CloseHandle(hInputWrite);
      return 0;
    }
    if (!CloseHandle(hInputWriteTmp)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes CloseHandle (hInputWriteTmp): %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      CloseHandle(hInputWrite);
      return 0;
    }
    
    /* Associates a C run-time file descriptor with an existing operating-system file handle. */
    *fdIn = _open_osfhandle((long) hOutputRead, 0);
    *fdOut = _open_osfhandle((long) hInputWrite, 0);
    
    /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window
     * for the new process. */
    ZeroMemory(&si,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdOutput = hOutputWrite;
    si.hStdInput = hInputRead;
    si.hStdError = hErrorWrite;
    si.wShowWindow = SW_HIDE;
   
    /* Launch the process that you want to redirect.  Example snmpd.conf pass_persist:
     * pass_persist    .1.3.6.1.4.1.2021.255  c:/perl/bin/perl c:/temp/pass_persisttest
    */
    if (!CreateProcess(NULL, cmd, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
      DEBUGMSGTL(("util_funcs","get_exec_pipes CreateProcess:'%s' %d\n",cmd, GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      CloseHandle(hInputWrite);
      return 0;
    }
    
    DEBUGMSGTL(("util_funcs","child hProcess (stored in pid): %d\n",(int)pi.hProcess));
    DEBUGMSGTL(("util_funcs","child dwProcessId (task manager): %d\n",(int)pi.dwProcessId));

    /* Set global child process handle */
    *pid = (int)pi.hProcess;

    /* Cleanup */
    if (!CloseHandle(pi.hThread))
      DEBUGMSGTL(("util_funcs","get_exec_pipes CloseHandle pi.hThread: %d\n",cmd));

   /* Close pipe handles to make sure that no handles to the write end of the
     * output pipe are maintained in this process or else the pipe will
     * not close when the child process exits and any calls to ReadFile 
     * will hang.
     */

    if (!CloseHandle(hOutputWrite)){
      DEBUGMSGTL(("util_funcs","get_exec_pipes CloseHandle hOutputWrite: %d\n",cmd, GetLastError()));
      return 0;
    }
    if (!CloseHandle(hInputRead)) {
      DEBUGMSGTL(("util_funcs","get_exec_pipes CloseHandle hInputRead: %d\n",cmd, GetLastError()));
      return 0;
    }
    if (!CloseHandle(hErrorWrite)) {
      DEBUGMSGTL(("util_funcs","get_exec_pipes CloseHandle hErrorWrite: %d\n",cmd, GetLastError()));
      return 0;
    }
    return 1;
#endif                          /* WIN32 */
    return 0;
}
コード例 #9
0
ファイル: util_funcs.c プロジェクト: OPSF/uClinux
int
get_exec_output(struct extensible *ex)
{
#if HAVE_EXECV && HAVE_FORK
    char            cachefile[STRMAX];
    char            cache[NETSNMP_MAXCACHESIZE];
    ssize_t         cachebytes;
    int             cfd;
#ifdef NETSNMP_EXCACHETIME
    long            curtime;
    static char     lastcmd[STRMAX];
    static int      lastresult;
#endif

    DEBUGMSGTL(("exec:get_exec_output","calling %s\n", ex->command));

    sprintf(cachefile, "%s/%s", get_persistent_directory(), NETSNMP_CACHEFILE);
#ifdef NETSNMP_EXCACHETIME
    curtime = time(NULL);
    if (curtime > (cachetime + NETSNMP_EXCACHETIME) ||
        strcmp(ex->command, lastcmd) != 0) {
        strcpy(lastcmd, ex->command);
        cachetime = curtime;
#endif

        cachebytes = NETSNMP_MAXCACHESIZE;
        ex->result = run_exec_command( ex->command, NULL, cache, &cachebytes );

        unlink(cachefile);
            /*
             * XXX  Use SNMP_FILEMODE_CLOSED instead of 644? 
             */
        if ((cfd = open(cachefile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
                snmp_log(LOG_ERR,"can not create cache file\n");
                setPerrorstatus(cachefile);
                cachetime = 0;
                return -1;
        }
        if (cachebytes > 0)
            write(cfd, (void *) cache, cachebytes);
        close(cfd);
#ifdef NETSNMP_EXCACHETIME
        lastresult = ex->result;
    } else {
        ex->result = lastresult;
    }
#endif
    DEBUGMSGTL(("exec:get_exec_output","using cached value\n"));
    if ((cfd = open(cachefile, O_RDONLY)) < 0) {
        snmp_log(LOG_ERR,"can not open cache file\n");
        setPerrorstatus(cachefile);
        return -1;
    }
    return (cfd);
#else                           /* !HAVE_EXECV || !HAVE_FORK */
#if defined(WIN32) && !defined(HAVE_EXECV)
/* MSVC and MinGW.  Cygwin already works as it has execv and fork */
    int         fd;   
    
    /* Reference:  MS tech note: 190351 */
    HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL;
        
    HANDLE hErrorWrite;
    SECURITY_ATTRIBUTES sa;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    
    sa.nLength= sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    DEBUGMSGTL(("exec:get_exec_output","calling %s\n", ex->command));
    
    /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */    
    if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes CreatePipe ChildOut: %d\n",
            GetLastError()));
      return -1;
    }
    
    /* Copy the stdout handle to the stderr handle in case the child closes one of 
     * its stdout handles. */
    if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite, GetCurrentProcess(),
          &hErrorWrite,0, TRUE,DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs", "get_exec_output DuplicateHandle: %d\n", GetLastError()));
      return -1;
    }

    /* Create new copies of the input and output handles but set bInheritHandle to 
     * FALSE so the new handle can not be inherited.  Otherwise the handles can not
     * be closed.  */
    if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(),
          &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs", "get_exec_output DupliateHandle ChildOut: %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      return -1;
    }   

    /* Close the temporary output and input handles */
    if (!CloseHandle(hOutputReadTmp)) {
      DEBUGMSGTL(("util_funcs", "get_exec_output CloseHandle (hOutputReadTmp): %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      return -1;
    }
    
    /* Associates a C run-time file descriptor with an existing operating-system file handle. */
    fd = _open_osfhandle((long) hOutputRead, 0);
    
    /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window
     * for the new process. */
    ZeroMemory(&si,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdOutput = hOutputWrite;
    si.hStdError = hErrorWrite;
    si.wShowWindow = SW_HIDE;
   
    /* Launch the process that you want to redirect.  Example snmpd.conf pass_persist:
     * pass_persist    .1.3.6.1.4.1.2021.255  c:/perl/bin/perl c:/temp/pass_persisttest
    */
    if (!CreateProcess(NULL, ex->command, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
      DEBUGMSGTL(("util_funcs","get_exec_output CreateProcess:'%s' %d\n",ex->command, GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      return -1;
    }
    
    /* Set global child process handle */
    ex->pid = (int)pi.hProcess;
    ex->tid = (int)pi.hThread;

    /* Close pipe handles to make sure that no handles to the write end of the
     * output pipe are maintained in this process or else the pipe will
     * not close when the child process exits and any calls to ReadFile 
     * will hang.
     */

    if (!CloseHandle(hOutputWrite)){
      DEBUGMSGTL(("util_funcs","get_exec_output CloseHandle hOutputWrite: %d\n",ex->command, GetLastError()));
      return -1;
    }
    if (!CloseHandle(hErrorWrite)) {
      DEBUGMSGTL(("util_funcs","get_exec_output CloseHandle hErrorWrite: %d\n",ex->command, GetLastError()));
      return -1;
    }
    return fd;
#endif                          /* WIN32 */
    return -1;
#endif
}
コード例 #10
0
ファイル: disk.c プロジェクト: Einheri/wl500g
unsigned char *var_extensible_disk(struct variable *vp,
				   oid *name,
				   int *length,
				   int exact,
				   int *var_len,
				   WriteMethod **write_method)
{

  int percent, iserror, disknum=0;
#if !defined(HAVE_SYS_STATVFS_H) && !defined(HAVE_STATFS)
  double totalblks, free, used, avail, availblks;
#else
  static long avail;
#endif
  static long long_ret;
  static char errmsg[300];

#if defined(HAVE_STATVFS) || defined(HAVE_STATFS)
#ifdef STAT_STATFS_FS_DATA
  struct fs_data fsd;
  struct {
    u_int f_blocks, f_bfree, f_bavail;
  } vfs;
#else
  struct statvfs vfs;
#endif
#else
#if HAVE_FSTAB_H
  int file;
  union {
     struct fs iu_fs;
     char dummy[SBSIZE];
  } sb;
#define filesys sb.iu_fs
#endif
#endif
  
  if (header_simple_table(vp,name,length,exact,var_len,write_method,numdisks))
    return(NULL);
  disknum = name[*length - 1] - 1;
  switch (vp->magic) {
    case MIBINDEX:
      long_ret = disknum+1;
      return((u_char *) (&long_ret));
    case ERRORNAME:       /* DISKPATH */
      *var_len = strlen(disks[disknum].path);
      return((u_char *) disks[disknum].path);
    case DISKDEVICE:
      *var_len = strlen(disks[disknum].device);
      return((u_char *) disks[disknum].device);
    case DISKMINIMUM:
      long_ret = disks[disknum].minimumspace;
      return((u_char *) (&long_ret));
    case DISKMINPERCENT:
      long_ret = disks[disknum].minpercent;
      return((u_char *) (&long_ret));
  }
#if defined(HAVE_SYS_STATVFS_H) || defined(HAVE_STATFS)
#ifdef STAT_STATFS_FS_DATA
  if (statvfs (disks[disknum].path, &fsd) == -1) {
#else
  if (statvfs (disks[disknum].path, &vfs) == -1) {
#endif
    fprintf(stderr,"Couldn't open device %s\n",disks[disknum].device);
    setPerrorstatus("statvfs dev/disk");
    return NULL;
  }
#ifdef STAT_STATFS_FS_DATA
  vfs.f_blocks = fsd.fd_btot;
  vfs.f_bfree  = fsd.fd_bfree;
  vfs.f_bavail = fsd.fd_bfreen;
#endif
#if defined(HAVE_ODS)
  vfs.f_blocks = vfs.f_spare[0];
  vfs.f_bfree  = vfs.f_spare[1];
  vfs.f_bavail = vfs.f_spare[2];
#endif
  percent = vfs.f_bavail <= 0 ? 100 :
    (int) ((double) (vfs.f_blocks - vfs.f_bfree) /
           (double) (vfs.f_blocks - (vfs.f_bfree - vfs.f_bavail)) * 100.0 + 0.5);
  avail = vfs.f_bavail;
#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
  if (vfs.f_frsize > 255)
    avail = avail * (vfs.f_frsize / 1024);
#endif
  iserror = (disks[disknum].minimumspace >= 0 ?
             avail < disks[disknum].minimumspace :
             100-percent <= disks[disknum].minpercent) ? 1 : 0;
  switch (vp->magic) {
    case DISKTOTAL:
      long_ret = vfs.f_blocks;
#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
      if (vfs.f_frsize > 255)
        long_ret = long_ret * (vfs.f_frsize / 1024);
#endif
      return((u_char *) (&long_ret));
    case DISKAVAIL:
      return((u_char *) (&avail));
    case DISKUSED:
      long_ret = (vfs.f_blocks - vfs.f_bfree);
#ifdef STRUCT_STATVFS_HAS_F_FRSIZE
      if (vfs.f_frsize > 255)
        long_ret = long_ret * (vfs.f_frsize / 1024);
#endif
      return((u_char *) (&long_ret));
    case DISKPERCENT:
      long_ret = percent;
      return ((u_char *) (&long_ret));
    case ERRORFLAG:
      long_ret = iserror;
      return((u_char *) (&long_ret));
    case ERRORMSG:
      if (iserror)
      {
	if (disks[disknum].minimumspace >= 0)
	  sprintf(errmsg,"%s: less than %d free (= %d)",disks[disknum].path,
                  disks[disknum].minimumspace, (int) avail);
	else
	  sprintf(errmsg,"%s: less than %d%% free (= %d%%)",disks[disknum].path,
		  disks[disknum].minpercent, percent);
      }
      else
        errmsg[0] = 0;
      *var_len = strlen(errmsg);
      return((u_char *) (errmsg));
  }
#else
#if HAVE_FSTAB_H
  /* read the disk information */
  if ((file = open(disks[disknum].device,0)) < 0) {
    fprintf(stderr,"Couldn't open device %s\n",disks[disknum].device);
    setPerrorstatus("open dev/disk");
    return(NULL);
  }
  lseek(file, (long) (SBLOCK * DEV_BSIZE), 0);
  if (read(file,(char *) &filesys, SBSIZE) != SBSIZE) {
    setPerrorstatus("open dev/disk");
    fprintf(stderr,"Error reading device %s\n",disks[disknum].device);
    close(file);
    return(NULL);
  }
  close(file);
  totalblks = filesys.fs_dsize;
  free = filesys.fs_cstotal.cs_nbfree * filesys.fs_frag +
    filesys.fs_cstotal.cs_nffree;
  used = totalblks - free;
  availblks = totalblks * (100 - filesys.fs_minfree) / 100;
  avail = availblks > used ? availblks - used : 0;
  percent = availblks == 0 ? 100 : (int) ((double) used / (double) totalblks * 100.0 + 0.5);
  iserror = (disks[disknum].minimumspace >= 0 ? avail * filesys.fs_fsize / 1024 <
	    disks[disknum].minimumspace : 100-percent <= disks[disknum].minpercent) ? 1 : 0;
  switch (vp->magic) {
    case DISKTOTAL:
      long_ret = (totalblks * filesys.fs_fsize / 1024);
      return((u_char *) (&long_ret));
    case DISKAVAIL:
      long_ret = avail * filesys.fs_fsize/1024;
      return((u_char *) (&long_ret));
    case DISKUSED:
      long_ret = used * filesys.fs_fsize/1024;
      return((u_char *) (&long_ret));
    case DISKPERCENT:
      long_ret = percent;
      return ((u_char *) (&long_ret));
    case ERRORFLAG:
      long_ret = iserror;
      return((u_char *) (&long_ret));
    case ERRORMSG:
      if (iserror)
	if (disks[disknum].minimumspace >= 0)
          sprintf(errmsg,"%s: less than %d free (= %d)",disks[disknum].path,
                  disks[disknum].minimumspace, avail * filesys.fs_fsize/1024);
	else
	  sprintf(errmsg,"%s: less than %d%% free (= %d%%)",disks[disknum].path,
		  disks[disknum].minpercent, percent);
      else
        errmsg[0] = 0;
      *var_len = strlen(errmsg);
      return((u_char *) (errmsg));
  }
#endif
#endif
  return NULL;
}