Exemplo n.º 1
0
void sftp_handle_new_dir(struct handleid *id, DIR *dp, const char *path) {
  ferrcheck(pthread_mutex_lock(&sftp_handle_lock));
  find_free_handle(id, SSH_FXP_OPENDIR);
  handles[id->id].u.dir = dp;
  handles[id->id].path = xstrdup(path);
  ferrcheck(pthread_mutex_unlock(&sftp_handle_lock));
}
Exemplo n.º 2
0
uint32_t sftp_handle_close(const struct handleid *id) {
  uint32_t rc;

  ferrcheck(pthread_mutex_lock(&sftp_handle_lock));
  if(id->id < nhandles
     && id->tag == handles[id->id].tag) {
    handles[id->id].tag = 0;            /* free up */
    switch(handles[id->id].type) {
    case SSH_FXP_OPEN:
      if(close(handles[id->id].u.fd) < 0)
        rc = HANDLER_ERRNO;
      else
        rc = 0;
      break;
    case SSH_FXP_OPENDIR:
      if(closedir(handles[id->id].u.dir) < 0)
        rc = HANDLER_ERRNO;
      else
        rc = 0;
      break;
    default:
      rc = SSH_FX_INVALID_HANDLE;
    }
    free(handles[id->id].path);
  }
  else
    rc = SSH_FX_INVALID_HANDLE;
  ferrcheck(pthread_mutex_unlock(&sftp_handle_lock));
  return rc;
}
Exemplo n.º 3
0
void sftp_handle_new_file(struct handleid *id, 
                     int fd, const char *path, unsigned flags) {
  ferrcheck(pthread_mutex_lock(&sftp_handle_lock));
  find_free_handle(id, SSH_FXP_OPEN);
  handles[id->id].u.fd = fd;
  handles[id->id].path = xstrdup(path);
  handles[id->id].flags = flags;
  ferrcheck(pthread_mutex_unlock(&sftp_handle_lock));
}
Exemplo n.º 4
0
unsigned sftp_handle_flags(const struct handleid *id) {
  unsigned rc;

  ferrcheck(pthread_mutex_lock(&sftp_handle_lock));
  if(id->id < nhandles
     && id->tag == handles[id->id].tag)
    rc = handles[id->id].flags;
  else
    rc = 0;
  ferrcheck(pthread_mutex_unlock(&sftp_handle_lock));
  return rc;
}
Exemplo n.º 5
0
void serialize_remove_job(struct sftpjob *job) {
  struct sqnode *q, **qq;

  ferrcheck(pthread_mutex_lock(&sq_mutex));
  for(qq = &newest; (q = *qq) && q->job != job; qq = &q->older)
    ;
  if(q) {
    *qq = q->older;
    free(q);
    /* Wake up anything that's waiting */
    ferrcheck(pthread_cond_broadcast(&sq_cond));
  }
  ferrcheck(pthread_mutex_unlock(&sq_mutex));
}
Exemplo n.º 6
0
uint32_t sftp_handle_get_dir(const struct handleid *id,
                        DIR **dp, const char **pathp) {
  uint32_t rc;

  ferrcheck(pthread_mutex_lock(&sftp_handle_lock));
  if(id->id < nhandles
     && id->tag == handles[id->id].tag
     && handles[id->id].type == SSH_FXP_OPENDIR) {
    *dp = handles[id->id].u.dir;
    if(pathp)
      *pathp = handles[id->id].path;
    rc = 0;
  } else
    rc = SSH_FX_INVALID_HANDLE;
  ferrcheck(pthread_mutex_unlock(&sftp_handle_lock));
  return rc;
}
Exemplo n.º 7
0
uint32_t sftp_handle_get_fd(const struct handleid *id,
                       int *fd, unsigned *flagsp) {
  uint32_t rc;

  ferrcheck(pthread_mutex_lock(&sftp_handle_lock));
  if(id->id < nhandles
     && id->tag == handles[id->id].tag
     && handles[id->id].type == SSH_FXP_OPEN) {
    *fd = handles[id->id].u.fd;
    if(flagsp)
      *flagsp = handles[id->id].flags;
    rc = 0;
  } else
    rc = SSH_FX_INVALID_HANDLE;
  ferrcheck(pthread_mutex_unlock(&sftp_handle_lock));
  return rc;
}
Exemplo n.º 8
0
void queue_serializable_job(struct sftpjob *job) {
  uint8_t type;
  uint32_t id;
  uint64_t offset, len64;
  uint32_t len;
  struct handleid hid;
  unsigned handleflags;
  struct sqnode *q;

  job->ptr = job->data;
  job->left = job->len;
  if(!sftp_parse_uint8(job, &type)
     && (type == SSH_FXP_READ || type == SSH_FXP_WRITE)
     && sftp_parse_uint32(job, &id) == SSH_FX_OK
     && sftp_parse_handle(job, &hid) == SSH_FX_OK
     && sftp_parse_uint64(job, &offset) == SSH_FX_OK
     && sftp_parse_uint32(job, &len) == SSH_FX_OK) {
    /* This is a well-formed read or write operation */
    len64 = len;
    handleflags = sftp_handle_flags(&hid);
  } else {
    /* Anything else has dummy values */
    memset(&hid, 0, sizeof hid);
    offset = 0;
    len64 = ~(uint64_t)0;
    handleflags = 0;
  }
  ferrcheck(pthread_mutex_lock(&sq_mutex));
  q = xmalloc(sizeof *q);
  q->older = newest;
  q->job = job;
  q->type = type;
  q->hid = hid;
  q->handleflags = handleflags;
  q->offset = offset;
  q->len = len64;
  newest = q;
  ferrcheck(pthread_mutex_unlock(&sq_mutex));
}
Exemplo n.º 9
0
void serialize(struct sftpjob *job) {
  struct sqnode *q, *oq;

  ferrcheck(pthread_mutex_lock(&sq_mutex));
  for(;;) {
    for(q = newest; q && q->job != job; q = q->older)
      ;
    /* If the job isn't in the queue then we process it straight away.  This
     * shouldn't happen... */
    if(!q)
      break;
    /* We've found our position in the queue.  See if there is any request on
     * the same handle which blocks our request. */
    for(oq = q->older; oq; oq = oq->older)
      if(!reorderable(q, oq, q->handleflags))
        break;
    if(!oq)
      break;
    /* We found an blocking request.  Wait for it to be removed. */
    ferrcheck(pthread_cond_wait(&sq_cond, &sq_mutex));
  }
  /* We did not find any blocking request.  We proceed. */
  ferrcheck(pthread_mutex_unlock(&sq_mutex));
}
Exemplo n.º 10
0
void sftp_send_end(struct worker *w) {
  ssize_t n, written;

  assert(w->bufused < 0x80000000);
  /* Fill in length word.  The malloc'd area is assumed to be aligned
   * suitably. */
  *(uint32_t *)w->buffer = htonl(w->bufused - 4);
  /* Write the complete output, protecting stdout with a lock to avoid
   * interleaving different responses. */
  ferrcheck(pthread_mutex_lock(&output_lock));
  if(sftp_debugging) {
    D(("%s:", sendtype));
    sftp_debug_hexdump(w->buffer + 4, w->bufused - 4);
  }
  /* Write the whole buffer, coping with short writes */
  written = 0;
  while((size_t)written < w->bufused)
    if((n = write(sftpout, w->buffer + written, w->bufused - written)) > 0)
      written += n;
    else if(n < 0)
      fatal("error sending response: %s", strerror(errno));
  ferrcheck(pthread_mutex_unlock(&output_lock));
  w->bufused = 0x80000000;
}