"Fossies" - the Fresh Open Source Software Archive 
Member "smbnetfs-0.6.3/src/function.c" (2 Mar 2019, 18095 Bytes) of package /linux/misc/smbnetfs-0.6.3.tar.bz2:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "function.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
0.6.1_vs_0.6.2.
1 #include "config.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stddef.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <dirent.h>
9 #include <sys/statvfs.h>
10 #include <sys/types.h>
11 #include <time.h>
12 #include <pthread.h>
13 #include <libsmbclient.h>
14 #include <glib.h>
15
16 #include "common.h"
17 #include "smbitem.h"
18 #include "samba.h"
19 #include "stat_workaround.h"
20 #include "function.h"
21
22 static int function_free_space_size = 0;
23 static int function_quiet_flag = 1;
24 static int function_show_dollar_shares = 0;
25 static int function_show_hidden_hosts = 0;
26 static int function_noexec_attr = 0;
27
28
29 int function_set_free_space_size(int blocks_count){
30 DPRINTF(7, "blocks_count=%d\n", blocks_count);
31 g_atomic_int_set(&function_free_space_size, blocks_count);
32 return 1;
33 }
34
35 static int function_get_free_space_size(void){
36 return g_atomic_int_get(&function_free_space_size);
37 }
38
39 int function_set_quiet_flag(int flag){
40 DPRINTF(7, "flag=%d\n", flag);
41 g_atomic_int_set(&function_quiet_flag, flag);
42 return 1;
43 }
44
45 static inline int function_get_quiet_flag(void){
46 return g_atomic_int_get(&function_quiet_flag);
47 }
48
49 int function_set_dollar_share_visibility(int flag){
50 DPRINTF(7, "flag=%d\n", flag);
51 g_atomic_int_set(&function_show_dollar_shares, flag);
52 return 1;
53 }
54
55 static inline int function_get_dollar_share_visibility(void){
56 return g_atomic_int_get(&function_show_dollar_shares);
57 }
58
59 int function_set_hidden_hosts_visibility(int flag){
60 DPRINTF(7, "flag=%d\n", flag);
61 g_atomic_int_set(&function_show_hidden_hosts, flag);
62 return 1;
63 }
64
65 static inline int function_get_hidden_hosts_visibility(void){
66 return g_atomic_int_get(&function_show_hidden_hosts);
67 }
68
69 int function_set_noexec_attr(int flag){
70 DPRINTF(7, "flag=%d\n", flag);
71 g_atomic_int_set(&function_noexec_attr, flag);
72 return 1;
73 }
74
75 static inline int function_get_noexec_attr(void){
76 return g_atomic_int_get(&function_noexec_attr);
77 }
78
79 static inline int function_check_xattr_name(const char *name){
80 static char *xattr_name = "system.nt_sec_desc.";
81 return (strncmp(name, xattr_name, strlen(xattr_name)) == 0);
82 }
83
84 static inline samba_fd function_get_fd(struct fuse_file_info *fi){
85 return (samba_fd) fi->fh;
86 }
87
88 static inline void function_store_fd(struct fuse_file_info *fi, samba_fd fd){
89 fi->fh = (uint64_t) fd;
90 }
91
92 static int function_open(const char *path, struct fuse_file_info *fi){
93 samba_fd fd;
94
95 DPRINTF(5, "(%s, flags=%o, fh=%llx)\n", path, fi->flags, (long long) fi->fh);
96 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
97
98 if ((fd = samba_open(path, fi->flags, 0777)) == NULL) return -errno;
99 function_store_fd(fi, fd);
100 return 0;
101 }
102
103 static int function_read(const char *path, char *buf, size_t size, off_t offset,
104 struct fuse_file_info *fi){
105 int result;
106 samba_fd fd;
107
108 DPRINTF(5, "(%s, %zd, fh=%llx, offset=%lld, flags=%o)\n", path, size,
109 (long long) fi->fh, (long long) offset, fi->flags);
110
111 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
112 result = samba_read(fd, offset, buf, size);
113 if (result == (ssize_t) (-1)) return -errno;
114 return result;
115 }
116
117 static int function_write(const char *path, const char *buf, size_t size,
118 off_t offset, struct fuse_file_info *fi){
119 int result;
120 samba_fd fd;
121
122 DPRINTF(5, "(%s, %zd, fh=%llx, offset=%lld, flags=%o)\n", path, size,
123 (long long) fi->fh, (long long) offset, fi->flags);
124
125 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
126 result = samba_write(fd, offset, (char *) buf, size);
127 if (result == (ssize_t) (-1)) return -errno;
128 return result;
129 }
130
131 static int function_close(const char *path, struct fuse_file_info *fi){
132 samba_fd fd;
133
134 DPRINTF(5, "(%s, fh=%llx, flags=%o)\n", path, (long long) fi->fh, fi->flags);
135
136 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
137 if (samba_close(fd) != 0) return -errno;
138 return 0;
139 }
140
141 static int function_unlink(const char *path){
142 DPRINTF(5, "(%s)\n", path);
143 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
144 if (samba_unlink(path) != 0) return -errno;
145 return 0;
146 }
147
148 static int function_rename(const char *from, const char *to){
149 DPRINTF(5, "(%s, %s)\n", from, to);
150 if (smbitem_what_is(from) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
151 if (smbitem_what_is(to) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
152 if (samba_rename(from, to) != 0) return -errno;
153 return 0;
154 }
155
156 static int function_opendir(const char *path, struct fuse_file_info *fi){
157 samba_fd fd;
158
159 DPRINTF(5, "(%s, flags=%o, fh=%llx)\n", path, fi->flags, (long long) fi->fh);
160 switch(smbitem_what_is(path)){
161 case SMBITEM_SMBNETFS_DIR:
162 function_store_fd(fi, (samba_fd) (-1));
163 return 0;
164
165 case SMBITEM_SMB_NAME:
166 case SMBITEM_SMB_SHARE:
167 case SMBITEM_SMB_SHARE_ITEM:
168 if ((fd = samba_opendir(path)) == NULL) return -errno;
169 function_store_fd(fi, fd);
170 return 0;
171
172 default:
173 return -ENOTDIR;
174 }
175 }
176
177 static int function_closedir(const char *path, struct fuse_file_info *fi){
178 samba_fd fd;
179
180 DPRINTF(5, "(%s, fh=%llx, flags=%o)\n", path, (long long) fi->fh, fi->flags);
181 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
182 if (fd == (samba_fd) (-1)) return 0;
183 if (samba_closedir(fd) != 0) return -errno;
184 return 0;
185 }
186
187 static int function_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
188 off_t offset, struct fuse_file_info *fi){
189 samba_fd fd;
190 int error, rec_cnt;
191 struct stat st;
192
193 (void) offset;
194 DPRINTF(5, "(%s)\n", path);
195
196 memset(&st, 0, sizeof(st));
197 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
198 if (fd == (samba_fd) (-1)){
199 int i, show_hidden_hosts;
200 struct smbitem *dir;
201
202 while(*path == '/') path++;
203 if ((dir = smbitem_getdir(path)) == NULL) return -EBADF;
204
205 error = EINVAL;
206 st.st_mode = S_IFDIR;
207 if (filler(buf, ".", &st, 0)) goto error0;
208 if (filler(buf, "..", &st, 0)) goto error0;
209
210 show_hidden_hosts = function_get_hidden_hosts_visibility();
211 for(i = 0; i < dir->child_cnt; i++){
212 switch(dir->childs[i]->type){
213 case SMBITEM_GROUP:
214 st.st_mode = S_IFDIR;
215 break;
216 case SMBITEM_HOST:
217 st.st_mode = S_IFDIR;
218 if (!show_hidden_hosts && dir->childs[i]->is_hidden) continue;
219 break;
220 case SMBITEM_LINK:
221 st.st_mode = S_IFLNK;
222 break;
223 default:
224 goto error0;
225 }
226 if (filler(buf, dir->childs[i]->name, &st, 0)) goto end;
227 }
228 error = 0;
229
230 error0:
231 smbitem_release_dir(dir);
232 return -error;
233 }
234
235 rec_cnt = 0;
236 while(*path == '/') path++;
237
238 while(1){
239 int count;
240 char readdir_buf[4096];
241 char name[1024];
242 char link[1024];
243 struct smb_conn_dirent_rec *rec;
244
245 count = samba_readdir(fd, readdir_buf, sizeof(readdir_buf));
246 if (count == 0) break;
247 if (count < 0){
248 error = errno;
249 goto end;
250 }
251
252 rec = (struct smb_conn_dirent_rec *) readdir_buf;
253 for( ; count >= (int) sizeof(struct smb_conn_dirent_rec);
254 count -= sizeof(struct smb_conn_dirent_rec)){
255
256 if (strcmp(rec->d_name, "") == 0) goto next_record;
257 if (strcmp(rec->d_name, ".") == 0) goto next_record;
258 if (strcmp(rec->d_name, "..") == 0) goto next_record;
259
260 switch(rec->smbc_type){
261 case SMBC_WORKGROUP:
262 error = EBADF;
263 goto end;
264
265 case SMBC_SERVER:
266 st.st_mode = S_IFDIR;
267 snprintf(name, sizeof(name), "%s/%s", path, rec->d_name);
268 snprintf(link, sizeof(link), "../%s", rec->d_name);
269 smbitem_mkgroup(path, SMBITEM_SAMBA_TREE);
270 smbitem_mkhost(rec->d_name, path, 1, SMBITEM_SAMBA_TREE);
271 smbitem_mklink(name, link, SMBITEM_SAMBA_TREE);
272 break;
273
274 case SMBC_FILE_SHARE:
275 st.st_mode = S_IFDIR;
276 if ((rec->d_name[strlen(rec->d_name) - 1] == '$') &&
277 ! function_get_dollar_share_visibility())
278 goto next_record;
279 break;
280
281 case SMBC_DIR:
282 st.st_mode = S_IFDIR;
283 break;
284
285 case SMBC_FILE:
286 st.st_mode = S_IFREG;
287 break;
288
289 default:
290 goto next_record;
291 }
292 if (rec_cnt == 0){
293 struct stat st;
294
295 error = EINVAL;
296 memset(&st, 0, sizeof(st));
297 st.st_mode = S_IFDIR;
298 if (filler(buf, ".", &st, 0)) goto end;
299 if (filler(buf, "..", &st, 0)) goto end;
300 rec_cnt += 2;
301 }
302 if (filler(buf, rec->d_name, &st, 0)){
303 error = EINVAL;
304 goto end;
305 }
306 rec_cnt++;
307
308 next_record:
309 rec++;
310 }
311 }
312
313 if (rec_cnt == 0){
314 error = EINVAL;
315 st.st_mode = S_IFDIR;
316 if (filler(buf, ".", &st, 0)) goto end;
317 if (filler(buf, "..", &st, 0)) goto end;
318 rec_cnt += 2;
319 }
320 error = 0;
321
322 end:
323 return -error;
324 }
325
326 static int function_mkdir(const char *path, mode_t mode){
327 DPRINTF(5, "(%s, %o)\n", path, mode);
328 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
329 if (samba_mkdir(path, mode) != 0) return -errno;
330 return 0;
331 }
332
333 static int function_rmdir(const char *path){
334 DPRINTF(5, "(%s)\n", path);
335 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
336 if (samba_rmdir(path) != 0) return -errno;
337 return 0;
338 }
339
340 static int function_stat(const char *path, struct stat *stbuf){
341 int i, count;
342 size_t len;
343 struct smbitem *dir;
344 char buf[2048];
345
346 DPRINTF(5, "(%s)\n", path);
347 if (stat_workaround_is_name_ignored(path)) return -ENOENT;
348 switch(smbitem_what_is(path)){
349 case SMBITEM_SMBNETFS_DIR:
350 while(*path == '/') path++;
351
352 count = 2;
353 if ((dir = smbitem_getdir(path)) == NULL) return -EINVAL;
354 for(i = 0; i < dir->child_cnt; i++)
355 switch(dir->childs[i]->type){
356 case SMBITEM_HOST:
357 case SMBITEM_GROUP:
358 count++;
359 break;
360 default:
361 break;
362 }
363 smbitem_release_dir(dir);
364
365 memset(stbuf, 0, sizeof(struct stat));
366 stbuf->st_mode = 0040777; /* protection */
367 stbuf->st_nlink = count; /* number of hard links */
368 stbuf->st_uid = 0; /* user ID of owner */
369 stbuf->st_gid = 0; /* group ID of owner */
370 stbuf->st_size = 0; /* total size, in bytes */
371 stbuf->st_blksize = 4096; /* blocksize for filesystem I/O */
372 return 0;
373
374 case SMBITEM_SMBNETFS_LINK:
375 DPRINTF(5, "link:(%s)\n", path);
376 if (smbitem_readlink(path, buf, sizeof(buf)) != 0) return -EINVAL;
377 len = strlen(buf);
378
379 memset(stbuf, 0, sizeof(struct stat));
380 stbuf->st_mode = 0120777; /* protection */
381 stbuf->st_nlink = 1; /* number of hard links */
382 stbuf->st_uid = 0; /* user ID of owner */
383 stbuf->st_gid = 0; /* group ID of owner */
384 stbuf->st_size = len; /* total size, in bytes */
385 stbuf->st_blksize = 4096; /* blocksize for filesystem I/O */
386 return 0;
387
388 case SMBITEM_SMB_NAME:
389 case SMBITEM_SMB_SHARE:
390 memset(stbuf, 0, sizeof(struct stat));
391 stbuf->st_mode = 0040777; /* protection */
392 stbuf->st_nlink = 2; /* number of hard links */
393 stbuf->st_uid = 0; /* user ID of owner */
394 stbuf->st_gid = 0; /* group ID of owner */
395 stbuf->st_size = 0; /* total size, in bytes */
396 stbuf->st_blksize = 4096; /* blocksize for filesystem I/O */
397 return 0;
398
399 case SMBITEM_SMB_SHARE_ITEM:
400 if (samba_stat(path, stbuf) != 0) return -errno;
401 if (S_ISREG(stbuf->st_mode) && function_get_noexec_attr())
402 stbuf->st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
403 return 0;
404
405 default:
406 return -EINVAL;
407 }
408 }
409
410 static int function_fstat(const char *path, struct stat *stbuf,
411 struct fuse_file_info *fi){
412 int i, count;
413 struct smbitem *dir;
414 samba_fd fd;
415
416 (void) path;
417
418 DPRINTF(5, "(%s)\n", path);
419 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
420 if (fd == (samba_fd) (-1)){
421 /* SMBNETFS_DIR */
422
423 while(*path == '/') path++;
424
425 count = 2;
426 if ((dir = smbitem_getdir(path)) == NULL) return -EBADF;
427 for(i = 0; i < dir->child_cnt; i++)
428 switch(dir->childs[i]->type){
429 case SMBITEM_HOST:
430 case SMBITEM_GROUP:
431 count++;
432 break;
433 default:
434 break;
435 }
436 smbitem_release_dir(dir);
437
438 memset(stbuf, 0, sizeof(struct stat));
439 stbuf->st_mode = 0040777; /* protection */
440 stbuf->st_nlink = count; /* number of hard links */
441 stbuf->st_uid = 0; /* user ID of owner */
442 stbuf->st_gid = 0; /* group ID of owner */
443 stbuf->st_size = 0; /* total size, in bytes */
444 stbuf->st_blksize = 4096; /* blocksize for filesystem I/O */
445 return 0;
446 }
447
448 if (samba_fstat(fd, stbuf) != 0) return -errno;
449 if (S_ISREG(stbuf->st_mode) && function_get_noexec_attr())
450 stbuf->st_mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
451 return 0;
452 }
453
454 static int function_ftruncate(const char *path, off_t size,
455 struct fuse_file_info *fi){
456 samba_fd fd;
457
458 DPRINTF(5, "(%s, %lld)\n", path, (long long) size);
459 if (size < 0) return -EINVAL;
460 if ((fd = function_get_fd(fi)) == NULL) return -EBADF;
461 if (samba_ftruncate(fd, size) != 0) return -errno;
462 return 0;
463 }
464
465 static int function_chmod(const char *path, mode_t mode){
466 DPRINTF(5, "(%s, %o)\n", path, mode);
467 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
468 if (samba_chmod(path, mode) != 0) return -errno;
469 return 0;
470 }
471
472 static int function_utimes(const char *path, struct utimbuf *buffer){
473 struct timeval tbuf[2];
474
475 DPRINTF(5, "(%s, %u)\n", path, (unsigned int)buffer->modtime);
476 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
477
478 tbuf[0].tv_sec = buffer->actime;
479 tbuf[0].tv_usec = 0;
480 tbuf[1].tv_sec = buffer->modtime;
481 tbuf[1].tv_usec = 0;
482
483 if (samba_utimes(path, tbuf) != 0) return -errno;
484 return 0;
485 }
486
487 /* libfuse does not support lsetxattr() and fsetxattr(), but samba does */
488 static int function_setxattr(const char *path, const char *name,
489 const char *value, size_t size, int flags){
490 DPRINTF(5, "(%s, name=%s, value=%s, size=%zd, flags=%o)\n", path,
491 name, value, size, flags);
492 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
493 if (!function_check_xattr_name(name)) return -ENOTSUP;
494 if (samba_setxattr(path, name, value, size, flags) != 0) return -errno;
495 return 0;
496 }
497
498 /* libfuse does not support lgetxattr() and fgetxattr(), but samba does */
499 static int function_getxattr(const char *path, const char *name,
500 char *value, size_t size){
501 DPRINTF(5, "(%s, name=%s, size=%zd)\n", path, name, size);
502 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
503 if (!function_check_xattr_name(name)) return -ENOTSUP;
504 if (samba_getxattr(path, name, value, size) != 0) return -errno;
505 return 0;
506 }
507
508 /* libfuse does not support llistxattr() and flistxattr(), but samba does */
509 static int function_listxattr(const char *path, char *list, size_t size){
510 DPRINTF(5, "(%s, size=%zd)\n", path, size);
511 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
512 if (samba_listxattr(path, list, size) != 0) return -errno;
513 return 0;
514 }
515
516 /* libfuse does not support lremovexattr() and fremovexattr(), but samba does */
517 static int function_removexattr(const char *path, const char *name){
518 DPRINTF(5, "(%s, name=%s)\n", path, name);
519 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -ENOTSUP;
520 if (!function_check_xattr_name(name)) return -ENOTSUP;
521 if (samba_removexattr(path, name) != 0) return -errno;
522 return 0;
523 }
524
525 static int function_readlink(const char *path, char *buf, size_t size){
526 DPRINTF(5, "(%s, %zd)\n", path, size);
527 if (smbitem_what_is(path) != SMBITEM_SMBNETFS_LINK) return -EINVAL;
528 if (smbitem_readlink(path, buf, size) != 0) return -EINVAL;
529 return 0;
530 }
531
532 static int function_mknod(const char *path, mode_t mode, dev_t rdev){
533 samba_fd fd;
534
535 (void) rdev;
536
537 DPRINTF(5, "(%s, %o)\n", path, mode);
538 if ((mode & S_IFMT) != S_IFREG) return -EPERM;
539 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
540 if ((fd = samba_creat(path, mode)) == NULL) return -errno;
541 if (samba_close(fd) != 0) return -errno;
542 return 0;
543 }
544
545 static int function_chown(const char *path, uid_t uid, gid_t gid){
546 (void) path;
547 (void) uid;
548 (void) gid;
549
550 DPRINTF(5, "(%s, uid=%d, gid=%d)\n", path, uid, gid);
551 if (function_get_quiet_flag()) return 0;
552 else return -EPERM;
553 }
554
555 static int function_truncate(const char *path, off_t size){
556 samba_fd fd;
557
558 DPRINTF(5, "(%s, %lld)\n", path, (long long) size);
559 if (size < 0) return -EINVAL;
560 if (smbitem_what_is(path) != SMBITEM_SMB_SHARE_ITEM) return -EINVAL;
561 if ((fd = samba_open(path, O_RDWR, 0777)) == NULL) return -errno;
562 if (samba_ftruncate(fd, size) != 0){
563 int error = errno;
564 samba_close(fd);
565 return -error;
566 }
567 if (samba_close(fd) != 0) return -errno;
568 return 0;
569 }
570
571 static int function_statfs(const char *path, struct statvfs *stbuf){
572 int free_space_blocks;
573
574 DPRINTF(5, "(%s)\n", path);
575
576 free_space_blocks = function_get_free_space_size();
577 memset(stbuf, 0, sizeof(struct statvfs));
578 stbuf->f_bsize = 4096;
579 stbuf->f_frsize = 4096;
580 if (free_space_blocks > 0){
581 stbuf->f_blocks = free_space_blocks;
582 stbuf->f_bfree = free_space_blocks;
583 stbuf->f_bavail = free_space_blocks;
584 stbuf->f_ffree = 32768;
585 stbuf->f_favail = 32768;
586 }
587 stbuf->f_namemax = FILENAME_MAX;
588 return 0;
589 }
590
591 struct fuse_operations smb_oper = {
592 .open = function_open,
593 .read = function_read,
594 .write = function_write,
595 .release = function_close,
596 .unlink = function_unlink,
597 .rename = function_rename,
598 .opendir = function_opendir,
599 .releasedir = function_closedir,
600 .readdir = function_readdir,
601 .mkdir = function_mkdir,
602 .rmdir = function_rmdir,
603 .getattr = function_stat,
604 .fgetattr = function_fstat,
605 .ftruncate = function_ftruncate,
606 .chmod = function_chmod,
607 .utime = function_utimes,
608 .setxattr = function_setxattr,
609 .getxattr = function_getxattr,
610 .listxattr = function_listxattr,
611 .removexattr= function_removexattr,
612 .readlink = function_readlink,
613 .mknod = function_mknod,
614 .chown = function_chown,
615 .truncate = function_truncate,
616 .statfs = function_statfs,
617 // .init = function_init, /* event.c */
618 // .destroy = function_destroy, /* event.c */
619 // .fsyncdir = function_fsyncdir,
620 // .access = function_access,
621 };