/* $Header: utils.c[1.14] Wed Sep 9 16:34:03 1992 nickel@cs.tu-berlin.de proposed $ This file is part of socket(1). Copyright (C) 1992 by Juergen Nickelsen Please read the file COPYRIGHT for further details. */ #ifdef sgi #define _BSD_SIGNALS #define SIG_HANDLER_RET int #else /* !sgi */ #define SIG_HANDLER_RET void #endif #include #include #include #include #include #include #ifdef ISC #define WNOHANG 1 #else #include #endif #include #include "globals.h" extern void initialize_siglist A((void)) ; /* Signal handler, print message and exit */ SIG_HANDLER_RET exitsig(sig) int sig ; { if (sig != SIGUSR1) { fprintf(stderr, "\n%s occured, exiting\n", sys_siglist[sig]) ; } exit(-sig) ; } /* Give usage message */ void usage() { static char ustring[] = "Usage: %s [-bclqrvw] [-p prog] [-s | host] port\n" ; fprintf(stderr, ustring, progname) ; } /* perror with progname */ void perror2(s) char *s ; { fprintf(stderr, "%s: ", progname) ; perror(s) ; } /* is s a number? */ int is_number(s) char *s ; { while (*s) { if (*s < '0' || *s > '9') { return 0 ; } s++ ; } return 1 ; } /* set up signal handling. All except TSTP, CONT, CLD, and QUIT * are caught with exitsig(). */ void init_signals() { int i ; #ifdef SIG_SETMASK /* only with BSD signals */ static struct sigvec svec = { exitsig, ~0, 0 } ; #endif initialize_siglist() ; /* shamelessly stolen from BASH */ for (i = 0; i < NSIG; i++) { switch (i) { #ifdef SIGTSTP case SIGTSTP: case SIGTTOU: case SIGTTIN: case SIGSTOP: case SIGCONT: continue ; #endif #if !defined (SIGCHLD) && defined (SIGCLD) #define SIGCHLD SIGCLD #endif #ifdef SIGCHLD case SIGCHLD: continue ; #endif #ifdef SIGWINCH case SIGWINCH: /* it is ridiculous to exit on WINCH */ continue ; #endif case SIGQUIT: /* if the user wants a core dump, */ continue ; /* they can have it. */ default: #ifdef SIG_SETMASK sigvec(i, &svec, NULL) ; #else signal(i, exitsig) ; #endif } } } /* connect stdin with prog's stdout/stderr and stdout * with prog's stdin. */ void open_pipes(prog) char *prog ; { int from_cld[2] ; /* from child process */ int to_cld[2] ; /* to child process */ /* create pipes */ if (pipe(from_cld) == -1) { perror2("pipe") ; exit(errno) ; } if (pipe(to_cld) == -1) { perror2("pipe") ; exit(errno) ; } /* for child process */ switch (fork()) { case 0: /* this is the child process */ /* connect stdin to pipe */ close(0) ; close(to_cld[1]) ; dup2(to_cld[0], 0) ; close(to_cld[0]) ; /* connect stdout to pipe */ close(1) ; close(from_cld[0]) ; dup2(from_cld[1], 1) ; /* connect stderr to pipe */ close(2) ; dup2(from_cld[1], 2) ; close(from_cld[1]) ; /* call program via sh */ execl("/bin/sh", "sh", "-c", prog, NULL) ; perror2("exec /bin/sh") ; /* terminate parent silently */ kill(getppid(), SIGUSR1) ; exit(255) ; case -1: perror2("fork") ; /* fork failed */ exit(errno) ; default: /* parent process */ /* connect stderr to pipe */ close(0) ; close(from_cld[1]) ; dup2(from_cld[0], 0) ; close(from_cld[0]) ; /* connect stderr to pipe */ close(1) ; close(to_cld[0]) ; dup2(to_cld[1], 1) ; close(to_cld[1]) ; } } /* remove zombie child processes */ void wait_for_children() { int wret, status ; #ifndef ISC struct rusage rusage ; #endif /* Just do a wait, forget result */ #ifndef ISC while ((wret = wait3(&status, WNOHANG, &rusage)) > 0) ; #else while ((wret = waitpid(-1, &status, WNOHANG)) > 0) ; #endif } /* expand LF characters to CRLF and adjust *sizep */ void add_crs(from, to, sizep) char *from, *to ; /* *from is copied to *to */ int *sizep ; { int countdown ; /* counter */ countdown = *sizep ; while (countdown) { if (*from == '\n') { *to++ = '\r' ; (*sizep)++ ; } *to++ = *from++ ; countdown-- ; } } /* strip CR characters from buffer and adjust *sizep */ void strip_crs(from, to, sizep) char *from, *to ; /* *from is copied to *to */ int *sizep ; { int countdown ; /* counter */ countdown = *sizep ; while (countdown) { if (*from == '\r') { from++ ; (*sizep)-- ; } else { *to++ = *from++ ; } countdown-- ; } } #define NULL_DEVICE "/dev/null" /* put yourself in the background */ void background() { int child_pid ; /* PID of child process */ int nulldev_fd ; /* file descriptor for null device */ child_pid = fork() ; switch (child_pid) { case -1: perror2("fork") ; exit(1) ; case 0: #ifdef NOSETSID ioctl(0, TIOCNOTTY, 0) ; #else setsid() ; #endif chdir("/") ; if ((nulldev_fd = open(NULL_DEVICE, O_RDWR, 0)) != -1) { int i ; for (i = 0; i < 3; i++) { if (isatty(i)) { dup2(nulldev_fd, i) ; } } close(nulldev_fd) ; } break ; default: exit(0) ; } }