Example #1
0
static VALUE rb_smbdir_initialize(VALUE self, VALUE smb_obj, VALUE url_obj)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMB_DATA_FROM_OBJ(smb_obj, smb_data);
  smbc_opendir_fn fn;
  const char *url = StringValueCStr(url_obj);

  fn = smbc_getFunctionOpendir(smb_data->smbcctx);
  data->smbcfile = (*fn)(smb_data->smbcctx, url);
  if (data->smbcfile == NULL) {
    rb_sys_fail_str(url_obj);
  }

  /* FIXME: Take encoding from argument */
  /* FIXME: Read unix charset (?) from smb.conf for default encoding */
  data->enc = rb_enc_find("UTF-8");

  data->smb_obj = smb_obj;
  data->smb_data = smb_data;
  data->smbcctx = smb_data->smbcctx;
  data->url = ruby_strdup(url);

  RB_SMB_DEBUG("smbcctx=%p smbcfile=%p\n", data->smbcctx, data->smbcfile);

  if (rb_block_given_p()) {
    return rb_ensure(rb_yield, self, rb_smbdir_close, self);
  }

  return self;
}
Example #2
0
static VALUE rb_smbfile_seek(int argc, VALUE *argv, VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);

  VALUE whence_num;
  rb_scan_args(argc, argv, "11", NULL, &whence_num);
  off_t offset = NUM2OFFT(argv[0]);
  int whence = NIL_P(whence_num) ? SEEK_SET : NUM2INT(whence_num);

  switch (whence) {
  case SEEK_SET:
    data->pos = offset;
    break;
  case SEEK_CUR:
    if (offset < 0 && offset < -data->pos) {
      errno = EINVAL;
      rb_sys_fail(data->url);
    }
    data->pos += offset;
    break;
  case SEEK_END:
    /* FIXME */
    rb_raise(rb_eNotImpError, "SEEK_END");
    break;
  default:
    errno = EINVAL;
    rb_sys_fail(data->url);
    break;
  }

  rb_smbfile_seek_by_data(data);

  return self;
}
Example #3
0
static VALUE rb_smbdir_read(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);
  smbc_readdir_fn fn;
  struct smbc_dirent *smbcdent;

  fn = smbc_getFunctionReaddir(data->smbcctx);

  errno = 0;
  smbcdent = (*fn)(data->smbcctx, data->smbcfile);

  if (smbcdent == NULL) {
    if (errno) {
      rb_sys_fail(data->url);
    }

    return Qnil;
  }

  VALUE args[4];
  args[0] = rb_external_str_new_with_enc(smbcdent->name,
      strlen(smbcdent->name), data->enc);
  args[1] = INT2NUM(smbcdent->smbc_type);
  args[2] = rb_str_new2(data->url);
  rb_str_cat2(args[2], "/"); /* FIXME: Unless if the last char is not "/" */
  rb_str_cat2(args[2], smbcdent->name); /* FIXME: Must be URL encoding */
  args[3] = rb_str_new(smbcdent->comment, smbcdent->commentlen);
  VALUE entry_obj = rb_class_new_instance(4, args, rb_cSMBDirEntry);

  return entry_obj;
}
Example #4
0
static VALUE rb_smbfile_pos(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);

  return SIZET2NUM(data->pos);
}
Example #5
0
static VALUE rb_smbdir_close(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);

  RB_SMB_DEBUG("data=%p smbcctx=%p smbcfile=%p\n", data, data->smbcctx, data->smbcfile);

  rb_smbdir_close_and_deref_by_data(data);

  return self;
}
Example #6
0
static VALUE rb_smbfile_read(int argc, VALUE *argv, VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);
  ssize_t req_read_size;
  VALUE str = rb_str_new2("");

  rb_smbfile_readable_p_by_data(data);

  if (argc == 0) {
    req_read_size = -1;
  }
  else {
    req_read_size = NUM2SSIZET(argv[0]);
    if (req_read_size == 0) {
      return str; /* Return empty string */
    }
    if (req_read_size < 0) {
      rb_raise(rb_eArgError, "Negative length given: %zd", req_read_size);
    }
  }

  while (req_read_size) {
    ssize_t buffer_read_size = data->buffer_used_size - data->buffer_pos;

    if (buffer_read_size == 0) {
      /* No remained data in buffer */
      rb_smbfile_read_by_data(data);

      if (data->eof) {
	/* No remained data in file */
	return (req_read_size > 0 && RSTRING_LEN(str) == 0) ? Qnil : str;
      }

      buffer_read_size = data->buffer_used_size - data->buffer_pos;
    }

    if (req_read_size > 0 && buffer_read_size > req_read_size) {
      buffer_read_size = req_read_size;
    }

    rb_str_cat(str, data->buffer + data->buffer_pos, buffer_read_size);

    data->pos += buffer_read_size;
    data->buffer_pos += buffer_read_size;
    if (req_read_size > 0) {
      req_read_size -= buffer_read_size;
    }
  }

  return str;
}
Example #7
0
static VALUE rb_smbdir_seek(VALUE self, VALUE offset_num)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);
  smbc_lseekdir_fn fn;
  off_t offset = (off_t)NUM2LONG(offset_num);

  fn = smbc_getFunctionLseekdir(data->smbcctx);

  errno = 0;
  if ((*fn)(data->smbcctx, data->smbcfile, offset) == -1) {
    rb_sys_fail(data->url);
  }

  return self;
}
Example #8
0
static VALUE rb_smbdir_tell(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);
  smbc_telldir_fn fn;
  off_t offset;

  fn = smbc_getFunctionTelldir(data->smbcctx);

  errno = 0;
  offset = (*fn)(data->smbcctx, data->smbcfile);
  if (offset == (off_t)-1) {
    if (errno != 0) {
      rb_sys_fail(data->url);
    }
  }

  return LONG2NUM(offset);
}
Example #9
0
static VALUE rb_smbfile_eof_p(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  RB_SMBFILE_DATA_CLOSED(data);

  if (data->buffer_used_size - data->buffer_pos > 0) {
    /* Remained data exist in buffer */
    return Qfalse;
  }

  /* Try to read from file to buffer */
  rb_smbfile_read_by_data(data);

  if (data->buffer_used_size - data->buffer_pos > 0) {
    /* Remained data exist in buffer */
    return Qfalse;
  }

  return Qtrue;
}
Example #10
0
static VALUE rb_smbdir_xattr_get(VALUE self, VALUE name_obj)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);

  return rb_smb_xattr_get(data->smb_obj, rb_str_new2(data->url), name_obj);
}
Example #11
0
static VALUE rb_smbdir_closed_p(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);

  return rb_smbdir_closed_p_by_data(data);
}
Example #12
0
static VALUE rb_smbdir_url(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);

  return rb_str_new2(data->url);
}
Example #13
0
static VALUE rb_smbdir_smb(VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);

  return data->smb_obj;
}
Example #14
0
static void rb_smbfile_read_by_data(RB_SMBFILE_DATA *data)
{
  smbc_read_fn fn;
  ssize_t read_size;
  char *buffer = data->buffer + data->buffer_used_size;
  size_t buffer_size = data->buffer_size - data->buffer_used_size;

  if (buffer_size == 0) {
    /* Buffer is full */
    if (data->buffer_pos < data->buffer_used_size) {
      /* But remained data exists */
      return;
    }

    /* Rewind */
    data->buffer_used_size = 0;
    data->buffer_pos = 0;
    buffer = data->buffer;
    buffer_size = data->buffer_size;
  }

  fn = smbc_getFunctionRead(data->smbcctx);

try:
  read_size = (*fn)(data->smbcctx, data->smbcfile, buffer, buffer_size);
  if (read_size < 0) {
    if (errno != EBADF) {
      rb_sys_fail("Bad SMBCFILE");
    }
    else {
      rb_smbfile_reopen_by_data(data);
      goto try;
    }
  }

  data->buffer_used_size += read_size;
  data->eof = (read_size == 0);
}

static VALUE rb_smbfile_close(VALUE self);

static VALUE rb_smbfile_initialize(int argc, VALUE *argv, VALUE self)
{
  RB_SMBFILE_DATA_FROM_OBJ(self, data);
  VALUE smb_obj, url_obj, mode_obj;

  rb_scan_args(argc, argv, "21", &smb_obj, &url_obj, &mode_obj);
  RB_SMB_DATA_FROM_OBJ(smb_obj, smb_data);

  if (NIL_P(mode_obj)) {
    data->fmode = FMODE_READABLE;
    // FIXME data->fmode = FMODE_READABLE | DEFAULT_TEXTMODE;
    data->oflags = O_RDONLY;
  }
  else if (FIXNUM_P(mode_obj)) {
    rb_raise(rb_eArgError, "FIXME");
    data->fmode = 0;
    data->oflags = NUM2INT(mode_obj);
  }
  else {
    const char *mode_str = StringValueCStr(mode_obj);
    data->fmode = rb_io_modestr_fmode(mode_str);
    data->oflags = rb_io_modestr_oflags(mode_str);
  }

  data->smb_obj = smb_obj;
  data->smb_data = smb_data;
  data->smbcctx = smb_data->smbcctx;
  data->url = ruby_strdup(RSTRING_PTR(url_obj));

  data->buffer = ruby_xmalloc(RB_SMBFILE_BUFFER_SIZE);
  data->buffer_size = RB_SMBFILE_BUFFER_SIZE;

  rb_smbfile_open_by_data(data);

  if (rb_block_given_p()) {
    return rb_ensure(rb_yield, self, rb_smbfile_close, self);
  }

  return self;
}