Example #1
0
int proxy_netio_postopen(pr_netio_stream_t *nstrm) {
  int res = 0, xerrno;
  pr_netio_t *curr_netio = NULL;

  if (nstrm == NULL) {
    errno = EINVAL;
    return -1;
  }

  curr_netio = proxy_netio_unset(nstrm->strm_type, "netio_postpopen");
  res = pr_netio_postopen(nstrm);
  xerrno = errno;
  proxy_netio_set(nstrm->strm_type, curr_netio);
 
  errno = xerrno;
  return res;
}
Example #2
0
File: data.c Project: flxflx/weasel
int pr_data_open(char *filename, char *reason, int direction, off_t size) {
  int res = 0;

  /* Make sure that any abort flags have been cleared. */
  session.sf_flags &= ~SF_ABORT;

  if (session.xfer.p == NULL) {
    data_new_xfer(filename, direction);

  } else {
    session.xfer.direction = direction;
  }

  if (!reason)
    reason = filename;

  /* Passive data transfers... */
  if (session.sf_flags & SF_PASSIVE ||
      session.sf_flags & SF_EPSV_ALL) {
    if (session.d == NULL) {
      pr_log_pri(PR_LOG_ERR, "Internal error: PASV mode set, but no data "
        "connection listening");
      pr_session_disconnect(NULL, PR_SESS_DISCONNECT_BY_APPLICATION, NULL);
    }

    res = data_pasv_open(reason, size);

  /* Active data transfers... */
  } else {
    if (session.d != NULL) {
      pr_log_pri(PR_LOG_ERR, "Internal error: non-PASV mode, yet data "
        "connection already exists?!?");
      pr_session_disconnect(NULL, PR_SESS_DISCONNECT_BY_APPLICATION, NULL);
    }

    res = data_active_open(reason, size);
  }

  if (res >= 0) {
    struct sigaction act;

    if (pr_netio_postopen(session.d->instrm) < 0) {
      pr_response_add_err(R_425, _("Unable to build data connection: %s"),
        strerror(session.d->xerrno));
      destroy_pool(session.d->pool);
      session.d = NULL;
      return -1;
    }

    if (pr_netio_postopen(session.d->outstrm) < 0) {
      pr_response_add_err(R_425, _("Unable to build data connection: %s"),
        strerror(session.d->xerrno));
      destroy_pool(session.d->pool);
      session.d = NULL;
      return -1;
    }

    memset(&session.xfer.start_time, '\0', sizeof(session.xfer.start_time));
    gettimeofday(&session.xfer.start_time, NULL);

    if (session.xfer.direction == PR_NETIO_IO_RD)
      nstrm = session.d->instrm;

    else
      nstrm = session.d->outstrm;

    session.sf_flags |= SF_XFER;

    if (timeout_noxfer)
      pr_timer_reset(PR_TIMER_NOXFER, ANY_MODULE);

    /* Allow aborts -- set the current NetIO stream to allow interrupted
     * syscalls, so our SIGURG handler can interrupt it
     */
    pr_netio_set_poll_interval(nstrm, 1);

    /* PORTABILITY: sigaction is used here to allow us to indicate
     * (w/ POSIX at least) that we want SIGURG to interrupt syscalls.  Put
     * in whatever is necessary for your arch here; probably not necessary
     * as the only _important_ interrupted syscall is select(), which on
     * any sensible system is interrupted.
     */

    act.sa_handler = data_urgent;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
#ifdef SA_INTERRUPT
    act.sa_flags |= SA_INTERRUPT;
#endif

    if (sigaction(SIGURG, &act, NULL) < 0)
      pr_log_pri(PR_LOG_WARNING,
        "warning: unable to set SIGURG signal handler: %s", strerror(errno));

#ifdef HAVE_SIGINTERRUPT
    /* This is the BSD way of ensuring interruption.
     * Linux uses it too (??)
     */
    if (siginterrupt(SIGURG, 1) < 0)
      pr_log_pri(PR_LOG_WARNING,
        "warning: unable to make SIGURG interrupt system calls: %s",
        strerror(errno));
#endif
  }

  return res;
}