Esempio n. 1
0
/* analyse a file system entry, referred by file name */
int filan_file(const char *filename, FILE *outfile) {
   int fd = -1;
   int result;
#if HAVE_STAT64
   struct stat64 buf = {0};
#else
   struct stat buf = {0};
#endif /* !HAVE_STAT64 */

   if (filan_followsymlinks) {
#if HAVE_STAT64
      result = Stat64(filename, &buf);
#else
      result = Stat(filename, &buf);
#endif /* !HAVE_STAT64 */
      if (result < 0) {
	 Warn3("stat(\"%s\", %p): %s", filename, &buf, strerror(errno));
      }
   } else {
#if HAVE_STAT64
      result = Lstat64(filename, &buf);
#else
      result = Lstat(filename, &buf);
#endif /* !HAVE_STAT64 */
      if (result < 0) {
	 Warn3("lstat(\"%s\", %p): %s", filename, &buf, strerror(errno));
      }
   }
   switch (buf.st_mode&S_IFMT) {
#ifdef S_IFSOCK
   case S_IFSOCK: /* probably, it's useless to make a socket and describe it */
      break;
#endif /* S_IFSOCK */
   default:
      if ((fd =
	   Open(filename,  O_RDONLY|O_NOCTTY|O_NONBLOCK
#ifdef O_LARGEFILE
		|O_LARGEFILE
#endif
		, 0700))
	  < 0) {
	 Warn2("open(\"%s\", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_LARGEFILE, 0700): %s",
	       filename, strerror(errno));
      }
   }
     
   result = filan_stat(&buf, fd, -1, outfile);
   fputc('\n', outfile);
   return result;
}
Esempio n. 2
0
/* register the sub process pid for passing of signals of type signum. 
   Only for SIGHUP, SIGINT, and SIGQUIT!
   returns 0 on success or <0 if an error occurred */
int xio_opt_signal(pid_t pid, int signum) {
   struct socat_sig_desc *sigdesc;

   if ((sigdesc = socat_get_sig_desc(signum)) == NULL) {
      Error("sub process registered for unsupported signal");
      return -1;
   }

   if (sigdesc->sig_use >= SOCAT_MAXPIDS) {
      Error1("too many sub processes registered for signal %d", signum);
      return -1;
   }
   if (sigdesc->sig_use == 0) {
      /* the special signal handler has not been registered yet - do it now */
#if HAVE_SIGACTION
      struct sigaction act;
      memset(&act, 0, sizeof(struct sigaction));
      act.sa_flags   = 0/*|SA_RESTART*/;
      act.sa_handler = socatsignalpass;
      sigfillset(&act.sa_mask);
      if (Sigaction(signum, &act, NULL) < 0) {
	 /*! man does not say that errno is defined */
	 Warn3("sigaction(%d, %p, NULL): %s", signum, &act, strerror(errno));
      }
#else
      Signal(signum, socatsignalpass);
#endif /* !HAVE_SIGACTION */
   }
   sigdesc->sig_pids[sigdesc->sig_use++] = pid;
   return 0;
}
Esempio n. 3
0
int xioshutdown(xiofile_t *sock, int how) {
   int result = 0;

   if (sock->tag == XIO_TAG_INVALID) {
      Error("xioshutdown(): invalid file descriptor");
      errno = EINVAL;
      return -1;
   }

   if (sock->tag == XIO_TAG_DUAL) {
      if ((how+1)&1) {
	 result = xioshutdown((xiofile_t *)sock->dual.stream[0], 0);
      }
      if ((how+1)&2) {
	 result |= xioshutdown((xiofile_t *)sock->dual.stream[1], 1);
      }
      return result;
   }

   switch (sock->stream.howtoshut) {
      char writenull;
   case XIOSHUT_NONE:
      return 0;
   case XIOSHUT_CLOSE:
      if (Close(sock->stream.fd) < 0) {
	 Info2("close(%d): %s",
	       sock->stream.fd, strerror(errno));
      }
      return 0;
   case XIOSHUT_DOWN:
      if ((result = Shutdown(sock->stream.fd, how)) < 0) {
	 Info3("shutdown(%d, %d): %s",
	       sock->stream.fd, how, strerror(errno));
      }
      return 0;
#if _WITH_SOCKET
   case XIOSHUT_NULL:
      /* send an empty packet; only useful on datagram sockets? */
      xiowrite(sock, &writenull, 0);
      return 0;
#endif /* _WITH_SOCKET */
   default: ;
   }

   if (false) {
      ;
#if WITH_OPENSSL
   } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_OPENSSL) {
      sycSSL_shutdown (sock->stream.para.openssl.ssl);
      /*! what about half/full close? */
#endif /* WITH_OPENSSL */

   } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_PIPE) {
      if ((how+1)&1) {
	 if (Close(sock->stream.fd) < 0) {
	    Info2("close(%d): %s",
		  sock->stream.fd, strerror(errno));
	 }
      }
      if ((how+1)&2) {
	 if (Close(sock->stream.para.bipipe.fdout) < 0) {
	    Info2("close(%d): %s",
		  sock->stream.para.bipipe.fdout, strerror(errno));
	 } 
      }
      
   } else if ((sock->stream.dtype & XIODATA_MASK) == XIODATA_2PIPE) {
      if ((how+1)&1) {
	 if (Close(sock->stream.fd) < 0) {
	    Info2("close(%d): %s",
		  sock->stream.fd, strerror(errno));
	 }
      }
      if ((how+1)&2) {
	 if (Close(sock->stream.para.exec.fdout) < 0) {
	    Info2("close(%d): %s",
		  sock->stream.para.exec.fdout, strerror(errno));
	 } 
      }
#if _WITH_SOCKET
   } else if (sock->stream.howtoend == END_SHUTDOWN) {
      if ((result = Shutdown(sock->stream.fd, how)) < 0) {
	 Info3("shutdown(%d, %d): %s",
	       sock->stream.fd, how, strerror(errno));
      }
   } else if (sock->stream.howtoend == END_SHUTDOWN_KILL) {
      if ((result = Shutdown(sock->stream.fd, how)) < 0) {
	 Info3("shutdown(%d, %d): %s",
	       sock->stream.fd, how, strerror(errno));
      }
      if ((sock->stream.flags&XIO_ACCMODE) == XIO_WRONLY) {
	 /* the child process might want to flush some data before terminating
	    */
	 int status = 0;

	 /* we wait for the child process to die, but to prevent timeout
	    we raise an alarm after some time.
	    NOTE: the alarm does not terminate waitpid() on Linux/glibc (BUG?),
	    therefore we have to do the kill in the signal handler */
	 {
	    struct sigaction act;
	    sigfillset(&act.sa_mask);
	    act.sa_flags = 0;
	    act.sa_handler = signal_kill_pid;
	    Sigaction(SIGALRM, &act, NULL);
	 }
	 socat_kill_pid = sock->stream.para.exec.pid;
#if HAVE_SETITIMER
	 /*! with next feature release, we get usec resolution and an option */
#else
	 Alarm(1 /*! sock->stream.para.exec.waitdie */);
#endif /* !HAVE_SETITIMER */
	 if (Waitpid(sock->stream.para.exec.pid, &status, 0) < 0) {
	    Warn3("waitpid("F_pid", %p, 0): %s",
		  sock->stream.para.exec.pid, &status, strerror(errno));
	 }
	 Alarm(0);
      }
   } else if ((sock->stream.dtype & XIODATA_MASK) ==
	      (XIODATA_RECVFROM & XIODATA_MASK)) {
      if (how >= 1) {
	 if (Close(sock->stream.fd) < 0) {
	    Info2("close(%d): %s",
		  sock->stream.fd, strerror(errno));
	 }
	 sock->stream.eof = 2;
	 sock->stream.fd = -1;
      }
#endif /* _WITH_SOCKET */
#if 0
   } else {
      Error1("xioshutdown(): bad data type specification %d", sock->stream.dtype);
      return -1;
#endif

   }
#if 0
   else if (sock->stream.howtoend == END_CLOSE &&