URI:
       Initial commit of prototype. - susmb - mounting of SMB/CIFS shares via FUSE
  HTML git clone git://git.codemadness.org/susmb
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 5f2b4da911cafeff284a07cb31b8bdca77e84ac8
   DIR parent d1d535c39adce75ac738e897f932070ff8966e6a
  HTML Author: geoff <devnull@localhost>
       Date:   Sat,  6 May 2006 22:02:40 +0000
       
       Initial commit of prototype.
       
       Diffstat:
         A Makefile                            |      19 +++++++++++++++++++
         A usmb.c                              |     211 +++++++++++++++++++++++++++++++
         A usmb.h                              |      13 +++++++++++++
         A usmb_dir.c                          |     104 +++++++++++++++++++++++++++++++
         A usmb_dir.h                          |      14 ++++++++++++++
         A usmb_file.c                         |      78 +++++++++++++++++++++++++++++++
         A usmb_file.h                         |      18 ++++++++++++++++++
         A utils.c                             |      66 +++++++++++++++++++++++++++++++
         A utils.h                             |       6 ++++++
       
       9 files changed, 529 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/Makefile b/Makefile
       @@ -0,0 +1,19 @@
       +SAMBA = /opt/samba
       +CC = gcc
       +CFLAGS = -Wall -W -std=c99 -pedantic -O $(shell pkg-config --cflags fuse) \
       +         -I$(SAMBA)/include -D_BSD_SOURCE -DFUSE_USE_VERSION=25 # -DDEBUG
       +LDLIBS = $(shell pkg-config --libs-only-l fuse) -lsmbclient
       +LDFLAGS = $(shell pkg-config --libs-only-L fuse) -L$(SAMBA)/lib
       +
       +SOURCES = usmb.c usmb_dir.c usmb_file.c utils.c
       +OBJECTS = $(SOURCES:.c=.o)
       +
       +PROGRAM = usmb
       +
       +all: $(PROGRAM)
       +
       +$(PROGRAM): $(OBJECTS)
       +        $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
       +
       +clean:
       +        $(RM) $(PROGRAM) $(OBJECTS)
   DIR diff --git a/usmb.c b/usmb.c
       @@ -0,0 +1,211 @@
       +#include <sys/time.h>        // struct timeval needed by libsmbclient.h
       +#include <libsmbclient.h>
       +#include <fuse.h>
       +#include <assert.h>
       +#include <errno.h>
       +#include <stdarg.h>
       +#include <stddef.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include "usmb.h"
       +#include "usmb_dir.h"
       +#include "usmb_file.h"
       +
       +
       +
       +#define INIT_LEN 256
       +static char * concat_strings (int num, ...)
       +{
       +  va_list ap;
       +
       +  char *base, *out;
       +
       +  base = out = malloc (INIT_LEN);
       +  if (NULL == base)
       +    return NULL;
       +
       +  size_t buff_size = INIT_LEN;
       +
       +  va_start (ap, num);
       +  for (int i = 0; i < num; ++i)
       +  {
       +    const char *next = va_arg (ap, const char *);
       +    assert (NULL != next);
       +
       +    size_t next_len = strlen (next);
       +    size_t required = (out - base) + next_len + 1;
       +
       +    if (buff_size < required)
       +    {
       +      while (buff_size < required)
       +      {
       +        size_t dbl_len = buff_size * 2;
       +        if (dbl_len < buff_size)
       +        {
       +          free (base);
       +          return NULL;
       +        }
       +
       +        buff_size = dbl_len;
       +      }
       +
       +      ptrdiff_t diff = out - base;
       +
       +      char *newbase = realloc (base, buff_size);
       +      if (NULL == newbase)
       +      {
       +        free (base);
       +        return NULL;
       +      }
       +
       +      base = newbase;
       +      out = base + diff;
       +    }
       +
       +    memcpy (out, next, next_len);
       +    out += next_len;
       +  }
       +  va_end (ap);
       +
       +  *out = '\0';
       +  return base;
       +}
       +
       +
       +static const char *share = "//127.0.0.1/geoff";
       +
       +char * make_url (const char *path)
       +{
       +  DEBUG (fprintf (stderr, "make_url (%s)\n", path));
       +  if ((NULL == path) || ('\0' == path[0]))
       +    return concat_strings (2, "smb:", share);
       +  else
       +    return concat_strings (3, "smb:", share, path);
       +}
       +
       +#if 0
       +static void dump_dirent (struct smbc_dirent *dirent)
       +{
       +  switch (dirent->smbc_type)
       +  {
       +    case SMBC_WORKGROUP:     fputs ("    Workgroup", stdout); break;
       +    case SMBC_SERVER:        fputs ("       Server", stdout); break;
       +    case SMBC_FILE_SHARE:    fputs ("   File Share", stdout); break;
       +    case SMBC_PRINTER_SHARE: fputs ("Printer Share", stdout); break;
       +    case SMBC_COMMS_SHARE:   fputs ("  Comms Share", stdout); break;
       +    case SMBC_IPC_SHARE:     fputs ("    IPC Share", stdout); break;
       +    case SMBC_DIR:           fputs ("    Directory", stdout); break;
       +    case SMBC_FILE:          fputs ("         File", stdout); break;
       +    case SMBC_LINK:          fputs ("         Link", stdout); break;
       +    default:                 fputs ("      Unknown", stdout); break;
       +  }
       +
       +  fputs (" - ", stdout);
       +
       +  puts (dirent->name);
       +}
       +#endif
       +
       +
       +static inline void do_strncpy (char *to, const char *from, int tolen)
       +{
       +  strncpy (to, from, tolen);
       +  to[tolen - 1] = '\0';
       +}
       +
       +
       +static void auth_fn (const char *srv, const char *shr, char *wg, int wglen,
       +                     char *un, int unlen, char *pw, int pwlen)
       +{
       +  DEBUG (fprintf (stderr, "Authenticating for \\\\%s\\%s\n", srv, shr));
       +
       +  do_strncpy (wg, "WORKGROUP", wglen);
       +  do_strncpy (un, "geoff", unlen);
       +  do_strncpy (pw, "ze]T72%5V", pwlen);
       +}
       +
       +
       +static void * usmb_init (void)
       +{
       +  return NULL;
       +}
       +
       +
       +static void usmb_destroy (void *unused)
       +{
       +  (void)unused;
       +}
       +
       +
       +#define usmb_readlink NULL
       +#define usmb_mknod NULL
       +#define usmb_unlink NULL
       +#define usmb_symlink NULL
       +#define usmb_rename NULL
       +#define usmb_chmod NULL
       +#define usmb_chown NULL
       +#define usmb_truncate NULL
       +#define usmb_utime NULL
       +#define usmb_statfs NULL
       +#define usmb_flush NULL
       +#define usmb_release NULL
       +#define usmb_fsync NULL
       +#define usmb_access NULL
       +#define usmb_create NULL
       +#define usmb_ftruncate NULL
       +
       +
       +static struct fuse_operations fuse_ops = {
       +  .getattr = usmb_getattr,
       +  .readlink = usmb_readlink,
       +  .getdir = NULL,
       +  .mknod = usmb_mknod,
       +  .mkdir = usmb_mkdir,
       +  .unlink = usmb_unlink,
       +  .rmdir = usmb_rmdir,
       +  .symlink = usmb_symlink,
       +  .rename = usmb_rename,
       +  .link = NULL,
       +  .chmod = usmb_chmod,
       +  .chown = usmb_chown,
       +  .truncate = usmb_truncate,
       +  .utime = usmb_utime,
       +  .open = usmb_open,
       +  .read = usmb_read,
       +  .write = usmb_write,
       +  .statfs = usmb_statfs,
       +  .flush = usmb_flush,
       +  .release = usmb_release,
       +  .fsync = usmb_fsync,
       +#ifdef SETXATTR
       +  .setxattr = usmb_setxattr,
       +  .getxattr = usmb_getxattr,
       +  .listxattr = usmb_listxattr,
       +  .removexattr = usmb_removexattr,
       +#endif
       +  .opendir = usmb_opendir,
       +  .readdir = usmb_readdir,
       +  .releasedir = usmb_releasedir,
       +  .fsyncdir = NULL,
       +  .init = usmb_init,
       +  .destroy = usmb_destroy,
       +  .access = usmb_access,
       +  .create = usmb_create,
       +  .ftruncate = usmb_ftruncate,
       +  .fgetattr = usmb_fgetattr
       +};
       +
       +  
       +
       +int main (int argc, char **argv)
       +{
       +  if (0 != smbc_init (auth_fn, 0))
       +  {
       +    perror ("Cannot initialise SMB library");
       +    return EXIT_FAILURE;
       +  }
       +
       +  return fuse_main (argc, argv, &fuse_ops);
       +}
       +
   DIR diff --git a/usmb.h b/usmb.h
       @@ -0,0 +1,13 @@
       +#ifndef USMB_H
       +  #define USMB_H
       +
       +  #ifdef DEBUG
       +    #undef DEBUG
       +    #define DEBUG(x) (x)
       +  #else
       +    #define DEBUG(x) ((void)0)
       +  #endif
       +
       +  char * make_url (const char *path);
       +
       +#endif
   DIR diff --git a/usmb_dir.c b/usmb_dir.c
       @@ -0,0 +1,104 @@
       +#include <sys/time.h>        // struct timeval needed by libsmbclient.h
       +#include <libsmbclient.h>
       +#include <fuse.h>
       +#include <dirent.h>
       +#include <errno.h>
       +#include <stdarg.h>
       +#include <stddef.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include "usmb_dir.h"
       +#include "usmb.h"
       +
       +
       +int usmb_mkdir (const char *dirname, mode_t mode)
       +{
       +  char *url = make_url (dirname);
       +  if (NULL == url)
       +    return -ENOMEM;
       +
       +  DEBUG (fprintf (stderr, "mkdir (%s)\n", url));
       +  int ret = smbc_mkdir (dirname, mode) ? -errno : 0;
       +  free (url);
       +  return ret;
       +}
       +
       +
       +int usmb_rmdir (const char *dirname)
       +{
       +  char *url = make_url (dirname);
       +  if (NULL == url)
       +    return -ENOMEM;
       +
       +  DEBUG (fprintf (stderr, "mkdir (%s)\n", url));
       +  int ret = smbc_rmdir (dirname) ? -errno : 0;
       +  free (url);
       +  return ret;
       +}
       +
       +
       +int usmb_opendir (const char *dirname, struct fuse_file_info *fi)
       +{
       +  char *url = make_url (dirname);
       +  if (NULL == url)
       +    return -ENOMEM;
       +
       +  DEBUG (fprintf (stderr, "opendir (%s)\n", url));
       +  int fd = smbc_opendir (url);
       +  fi->fh = fd;
       +
       +  int ret = (fd < 0) ? -errno : 0;
       +  free (url);
       +  return ret;
       +}
       +
       +
       +int usmb_readdir (const char *path, void *h, fuse_fill_dir_t filler,
       +                  off_t offset, struct fuse_file_info *fi)
       +{
       +  (void)path;
       +  (void)offset;
       +
       +  DEBUG (fprintf (stderr, "readdir (%s)\n", path));
       +
       +  struct smbc_dirent *dirent;
       +  errno = 0;
       +  while (NULL != (dirent = smbc_readdir (fi->fh)))
       +  {
       +    struct stat stbuf;
       +
       +    switch (dirent->smbc_type)
       +    {
       +      case SMBC_DIR:
       +        stbuf.st_mode = DT_DIR << 12;
       +        break;
       +
       +      case SMBC_FILE:
       +        stbuf.st_mode = DT_REG << 12;
       +        break;
       +
       +      case SMBC_LINK:
       +        stbuf.st_mode = DT_LNK << 12;
       +        break;
       +
       +      default:
       +        break;
       +    }
       +
       +    if (1 == filler (h, dirent->name, &stbuf, 0))  /* if error */
       +      return -1;
       +  }
       +
       +  return -errno;
       +}
       +
       +
       +int usmb_releasedir (const char *path, struct fuse_file_info *fi)
       +{
       +  (void)path;
       +
       +  DEBUG (fprintf (stderr, "releasedir (%s)\n", path));
       +  return (smbc_closedir (fi->fh) < 0) ? -errno : 0;
       +}
       +
   DIR diff --git a/usmb_dir.h b/usmb_dir.h
       @@ -0,0 +1,14 @@
       +#ifndef USMB_DIR_H
       +  #define USMB_DIR_H
       +
       +  #include <sys/types.h>
       +  #include <fuse.h>
       +
       +  int usmb_mkdir (const char *dirname, mode_t mode);
       +  int usmb_rmdir (const char *dirname);
       +  int usmb_opendir (const char *dirname, struct fuse_file_info *fi);
       +  int usmb_readdir (const char *path, void *h, fuse_fill_dir_t filler,
       +                    off_t offset, struct fuse_file_info *fi);
       +  int usmb_releasedir (const char *path, struct fuse_file_info *fi);
       +
       +#endif
   DIR diff --git a/usmb_file.c b/usmb_file.c
       @@ -0,0 +1,78 @@
       +#include <sys/time.h>        // struct timeval needed by libsmbclient.h
       +#include <libsmbclient.h>
       +#include <fuse.h>
       +#include <errno.h>
       +#include <stddef.h>
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include "usmb_file.h"
       +#include "usmb.h"
       +
       +
       +int usmb_getattr (const char *filename, struct stat *st)
       +{
       +  char *url = make_url (filename);
       +  DEBUG (fprintf (stderr, "stat (%s)\n", url));
       +
       +  int ret = smbc_stat (url, st);
       +  free (url);
       +  return (ret < 0) ? -errno : 0;
       +}
       +
       +
       +int usmb_fgetattr (const char *filename, struct stat *st,
       +                   struct fuse_file_info *fi)
       +{
       +  (void)filename;
       +  return (smbc_fstat (fi->fh, st) < 0) ? -errno : 0;
       +}
       +
       +
       +int usmb_open (const char *filename, struct fuse_file_info *fi)
       +{
       +  char *url = make_url (filename);
       +  if (NULL == url)
       +    return -ENOMEM;
       +
       +  DEBUG (fprintf (stderr, "open (%s)\n", url));
       +
       +  int fd = smbc_open (url, 0, 0);
       +  int ret = (fd < 0) ? -errno : 0;
       +  fi->fh = fd;
       +
       +  free (url);
       +  return ret;
       +}
       +
       +
       +int usmb_release (const char *filename, struct fuse_file_info *fi)
       +{
       +  (void)filename;
       +  return (smbc_close (fi->fh) < 0) ? -errno : 0;
       +}
       +
       +
       +int usmb_read (const char *filename, char *buff, size_t len, off_t off,
       +               struct fuse_file_info *fi)
       +{
       +  (void)filename;
       +  (void)off;
       +
       +  /* TODO: this may be WRONG: do we need to consider the offset */
       +  DEBUG (fprintf (stderr, "read (%p, %u)\n", buff, len));
       +  return smbc_read (fi->fh, buff, len);
       +}
       +
       +
       +int usmb_write (const char *filename, const char *buff, size_t len, off_t off,
       +                struct fuse_file_info *fi)
       +{
       +  (void)filename;
       +  (void)off;
       +
       +  /* TODO: this may be WRONG: do we need to consider the offset */
       +  DEBUG (fprintf (stderr, "write (%p, %u)\n", buff, len));
       +  return smbc_write (fi->fh, (char *)buff, len) ? -errno : 0;
       +}
       +
   DIR diff --git a/usmb_file.h b/usmb_file.h
       @@ -0,0 +1,18 @@
       +#ifndef USMB_FILE_H
       +  #define USMB_FILE_H
       +
       +  #include <fuse.h>
       +  #include <stddef.h>
       +  #include <sys/types.h>
       +
       +  int usmb_getattr (const char *filename, struct stat *st);
       +  int usmb_fgetattr (const char *filename, struct stat *st,
       +                     struct fuse_file_info *fi);
       +  int usmb_open (const char *filename, struct fuse_file_info *fi);
       +  int usmb_release (const char *filename, struct fuse_file_info *fi);
       +  int usmb_read (const char *filename, char *buff, size_t len, off_t off,
       +                 struct fuse_file_info *fi);
       +  int usmb_write (const char *filename, const char *buff, size_t len, off_t off,
       +                  struct fuse_file_info *fi);
       +
       +#endif
   DIR diff --git a/utils.c b/utils.c
       @@ -0,0 +1,66 @@
       +#include <assert.h>
       +#include <stdarg.h>
       +#include <stddef.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include "utils.h"
       +
       +
       +#define INIT_LEN 256
       +char * concat_strings (int num, ...)
       +{
       +  va_list ap;
       +
       +  char *base, *out;
       +
       +  base = out = malloc (INIT_LEN);
       +  if (NULL == base)
       +    return NULL;
       +
       +  size_t buff_size = INIT_LEN;
       +
       +  va_start (ap, num);
       +  for (int i = 0; i < num; ++i)
       +  {
       +    const char *next = va_arg (ap, const char *);
       +    assert (NULL != next);
       +
       +    size_t next_len = strlen (next);
       +    size_t required = (out - base) + next_len + 1;
       +
       +    if (buff_size < required)
       +    {
       +      while (buff_size < required)
       +      {
       +        size_t dbl_len = buff_size * 2;
       +        if (dbl_len < buff_size)
       +        {
       +          free (base);
       +          return NULL;
       +        }
       +
       +        buff_size = dbl_len;
       +      }
       +
       +      ptrdiff_t diff = out - base;
       +
       +      char *newbase = realloc (base, buff_size);
       +      if (NULL == newbase)
       +      {
       +        free (base);
       +        return NULL;
       +      }
       +
       +      base = newbase;
       +      out = base + diff;
       +    }
       +
       +    memcpy (out, next, next_len);
       +    out += next_len;
       +  }
       +  va_end (ap);
       +
       +  *out = '\0';
       +  return base;
       +}
       +
   DIR diff --git a/utils.h b/utils.h
       @@ -0,0 +1,6 @@
       +#ifndef UTILS_H
       +  #define UTILS_H
       +
       +  char * concat_strings (int num, ...);
       +
       +#endif