Revert statfs change.
[usmb.git] / usmb.c
blob51d3603996d96d16834faff4b2b3ab7c6869ab14
1 /* usmb - mount SMB shares via FUSE and Samba
2 * Copyright (C) 2006-2007 Geoff Johnstone
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include <sys/time.h> // struct timeval needed by libsmbclient.h
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <libsmbclient.h>
24 #include <fuse.h>
25 #include <assert.h>
26 #include <errno.h>
27 #include <stdarg.h>
28 #include <stdbool.h>
29 #include <stddef.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include "conffile.h"
34 #include "options.h"
35 #include "usmb.h"
36 #include "usmb_dir.h"
37 #include "usmb_file.h"
38 #include "utils.h"
39 #include "version.h"
42 SMBCCTX *ctx;
43 static char *server, *share, *mountpoint, *options,
44 *domain, *username, *password;
47 char * make_url (const char *path)
49 assert (NULL != share);
51 if ((NULL == path) || ('\0' == path[0]))
52 return xstrdup (share);
53 else
54 return concat_strings (2, share, path);
58 static inline void do_strncpy (char *to, const char *from, int tolen)
60 strncpy (to, from, tolen);
61 to[tolen - 1] = '\0';
65 static void auth_fn (const char *srv, const char *shr, char *wg, int wglen,
66 char *un, int unlen, char *pw, int pwlen)
68 (void)srv;
69 (void)shr;
70 DEBUG (fprintf (stderr, "Authenticating for \\\\%s\\%s\n", srv, shr));
71 DEBUG (fprintf (stderr, "Domain: %s; User: %s; Password:%s\n",
72 domain, username, password));
74 if (NULL != domain)
75 do_strncpy (wg, domain, wglen);
77 do_strncpy (un, username, unlen);
78 do_strncpy (pw, password, pwlen);
82 static bool create_smb_context (char *domain, char *username, SMBCCTX **pctx)
84 *pctx = smbc_new_context();
86 if (NULL == *pctx)
88 perror ("Cannot create SMB context");
89 return false;
92 (*pctx)->workgroup = domain;
93 (*pctx)->user = username;
94 (*pctx)->timeout = 5000;
95 (*pctx)->callbacks.auth_fn = auth_fn;
97 if (NULL == smbc_init_context (*pctx))
99 perror ("Cannot initialise SMB context");
100 smbc_free_context (*pctx, 1);
101 return false;
104 return true;
108 #if 0
109 static int usmb_statfs (const char *path, struct statvfs *vfs)
111 if ((NULL == path) || (NULL == vfs))
112 return -EINVAL;
114 memset (vfs, 0, sizeof (*vfs));
116 vfs->f_bsize = 32768;
117 vfs->f_blocks = 0x7FFFFFFFl;
118 vfs->f_bfree = 0x7FFFFFFFl;
119 vfs->f_bavail = 0x7FFFFFFFl;
121 return 0;
123 #endif
126 static void * usmb_init (struct fuse_conn_info *conn)
128 DEBUG (fputs ("usmb_init()\n", stderr));
129 (void)conn;
130 return NULL;
134 static void usmb_destroy (void *unused)
136 (void)unused;
137 DEBUG (fputs ("usmb_destroy()\n", stderr));
141 // probably won't (can't ?) implement these:
142 // readlink mknod symlink flush fsync
144 // fuse.h says "Just a placeholder, don't set".
145 // statfs
147 // no easy way of implementing these.
148 // access ftruncate
150 #ifdef __lint
151 #define SET_ELEMENT(name,value) value
152 #else
153 #define SET_ELEMENT(name,value) name = value
154 #endif
155 static struct fuse_operations fuse_ops = {
156 SET_ELEMENT (.getattr, usmb_getattr),
157 SET_ELEMENT (.readlink, NULL),
158 SET_ELEMENT (.getdir, NULL),
159 SET_ELEMENT (.mknod, NULL),
160 SET_ELEMENT (.mkdir, usmb_mkdir),
161 SET_ELEMENT (.unlink, usmb_unlink),
162 SET_ELEMENT (.rmdir, usmb_rmdir),
163 SET_ELEMENT (.symlink, NULL),
164 SET_ELEMENT (.rename, usmb_rename),
165 SET_ELEMENT (.link, NULL),
166 SET_ELEMENT (.chmod, usmb_chmod),
167 SET_ELEMENT (.chown, NULL), // usmb_chown, --not implemented in libsmbclient
168 SET_ELEMENT (.truncate, usmb_truncate),
169 SET_ELEMENT (.utime, usmb_utime),
170 SET_ELEMENT (.open, usmb_open),
171 SET_ELEMENT (.read, usmb_read),
172 SET_ELEMENT (.write, usmb_write),
173 SET_ELEMENT (.statfs, NULL),
174 SET_ELEMENT (.flush, NULL),
175 SET_ELEMENT (.release, usmb_release),
176 SET_ELEMENT (.fsync, NULL),
177 SET_ELEMENT (.setxattr, usmb_setxattr),
178 SET_ELEMENT (.getxattr, usmb_getxattr),
179 SET_ELEMENT (.listxattr, usmb_listxattr),
180 SET_ELEMENT (.removexattr, usmb_removexattr),
181 SET_ELEMENT (.opendir, usmb_opendir),
182 SET_ELEMENT (.readdir, usmb_readdir),
183 SET_ELEMENT (.releasedir, usmb_releasedir),
184 SET_ELEMENT (.fsyncdir, NULL),
185 SET_ELEMENT (.init, usmb_init),
186 SET_ELEMENT (.destroy, usmb_destroy),
187 SET_ELEMENT (.access, NULL),
188 SET_ELEMENT (.create, usmb_create),
189 SET_ELEMENT (.ftruncate, NULL),
190 SET_ELEMENT (.fgetattr, usmb_fgetattr),
191 SET_ELEMENT (.lock, NULL), // TODO: implement
192 SET_ELEMENT (.utimens, NULL), // TODO: implement
193 SET_ELEMENT (.bmap, NULL), // TODO: implement
197 // this should really open() the file and check the fd, but the XML parser
198 // takes a filename, not a file descriptor
199 static bool check_conf_perms (const char *conffile)
201 struct stat buf;
202 if (0 == stat (conffile, &buf))
204 if (getuid() != buf.st_uid)
206 fprintf (stderr, "You do not own the configuration file %s\n",
207 conffile);
208 return false;
211 if (buf.st_mode & (S_IRWXG | S_IRWXO))
213 fprintf (stderr, "Configuration file %s is accessible to non-owner\n",
214 conffile);
215 return false;
218 else
220 fprintf (stderr, "Cannot stat configuration file %s: %s\n",
221 conffile, strerror (errno));
222 return false;
225 return true;
229 static bool create_share_name (const char *server, const char *sharename)
231 size_t len = strlen ("smb:///") +
232 strlen (server) +
233 strlen (sharename) + 1;
235 if (NULL == (share = malloc (len)))
237 perror ("Cannot allocate share name");
238 return false;
241 snprintf (share, len, "smb://%s/%s", server, sharename);
242 DEBUG (fprintf (stderr, "Share URL: %s\n", share));
243 return true;
247 static void free_strings (char *sharename)
249 xfree (sharename);
250 xfree (password);
251 xfree (username);
252 xfree (domain);
253 xfree (options);
254 xfree (mountpoint);
255 xfree (share);
256 xfree (server);
260 int main (int argc, char **argv)
262 const char *conffile, *mountid;
263 char *sharename = NULL;
266 static char conf[256];
267 snprintf (conf, sizeof (conf), "%s/.usmb.conf", getenv ("HOME"));
268 conffile = conf;
271 if (!parse_args (&argc, &argv, &mountid, &conffile))
272 return EXIT_FAILURE;
274 if (!check_conf_perms (conffile) ||
275 !conffile_get_mount (conffile, mountid,
276 &server, &sharename, &mountpoint, &options,
277 &domain, &username, &password))
278 return EXIT_FAILURE;
280 if (!create_share_name (server, sharename) ||
281 !create_smb_context (domain, username, &ctx))
283 free_strings (sharename);
284 return EXIT_FAILURE;
287 DEBUG (fprintf (stderr, "Username: %s\\%s\n", domain, username));
288 show_about (stdout);
290 int fuse_argc;
291 char **fuse_argv;
292 build_fuse_args (options, mountpoint, &fuse_argc, &fuse_argv);
293 int ret = fuse_main (fuse_argc, fuse_argv, &fuse_ops, NULL);
295 smbc_free_context (ctx, 1);
296 free_strings (sharename);
298 return ret;