"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "chironfs-1.1.1/src/chirctl.c" of archive chironfs-1.1.1.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* Copyright 2005-2008 Luis Furquim
2 *
3 *
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; version 3 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 */
18
19
20
21 //
22 // The lines below are from a patch contributed by Yen-Ming Lee,
23 // porting ChironFS to FreeBSD
24 //
25 #include <fuse.h>
26 #if defined(linux) || defined(__FreeBSD__)
27
28 #include <fuse/fuse.h>
29 #include <fuse/fuse_opt.h>
30
31 #else
32
33 typedef uint64_t cpuset_t;
34
35 //
36 // The lines below are from a patch contributed by Antti Kantee
37 // to make ChironFS run on NetBSD
38 //
39
40 #include <fuse_opt.h>
41
42 #endif
43 //
44 // End of BSD patches
45 //
46
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <stdarg.h>
51 #include <unistd.h>
52 #include <fcntl.h>
53 #include <dirent.h>
54 #include <errno.h>
55 #include <time.h>
56 #include <sys/time.h>
57
58 #include <sys/statvfs.h>
59
60 #include <sys/stat.h>
61
62 #include <stdint.h>
63 #include <pwd.h>
64 #include <grp.h>
65
66
67 #ifdef __linux__
68
69 #define _REENTRANT
70
71 #ifndef _POSIX_SOURCE
72 #define _POSIX_SOURCE
73 #endif
74
75 /* for LinuxThreads */
76 #define _P __P
77
78 #endif
79
80 #include <pthread.h>
81
82 #include "config.h"
83
84 #include "chiron-types.h"
85 #include "chirondbg.h"
86 #define _CHIRON_CTL_H_
87 #include "chirctl.h"
88 #include "chironfn.h"
89
90
91
92
93 ctlfs_entry_t mkstatnod(char *path, unsigned long mode, unsigned short uid, unsigned short gid)
94 {
95 ctlfs_entry_t c;
96
97 memset(&c,0,sizeof(ctlfs_entry_t));
98 c.path = path;
99 c.attr.st_mode = mode;
100 c.attr.st_ino = ++inode_count;
101 c.attr.st_dev = 0;
102 c.attr.st_nlink = 0;
103 c.attr.st_uid = uid;
104 c.attr.st_gid = gid;
105 c.attr.st_size = 1;
106 c.attr.st_atime = 0;
107 c.attr.st_mtime = 0;
108 c.attr.st_ctime = 0;
109 c.attr.st_blocks = 0;
110 c.attr.st_blksize = 0;
111 c.ctlfs = NULL;
112 return(c);
113 }
114
115 void free_ctlnode(ctlfs_entry_t *ctlroot)
116 {
117 ctlfs_entry_t *c = ctlroot;
118 for(;c->path!=NULL;++c) {
119 if (c->ctlfs!=NULL) {
120 free_ctlnode(c->ctlfs);
121 }
122 free(c->path);
123 }
124 free(ctlroot);
125 }
126
127 int mkctlfs()
128 {
129 int i;
130 struct stat st;
131 // uid_t uid = geteuid();
132 // gid_t gid = getegid();
133
134
135 i = stat(chironctl_mountpoint,&st);
136 if (i) {
137 return(-1);
138 }
139
140 ctlfs[0] = mkstatnod("/",S_IFDIR | S_IREAD | S_IEXEC | ((S_IREAD | S_IEXEC)>>3),st.st_uid,st.st_gid);
141 ctlfs[0].ctlfs = malloc(sizeof(ctlfs_entry_t)*max_replica+1);
142 if (ctlfs[0].ctlfs==NULL) {
143 return(-1);
144 }
145 ctlfs[1].path = NULL;
146 dbg(("\nalloced"));
147
148 for(i=0;i<max_replica;++i) {
149 ctlfs->ctlfs[i] = mkstatnod(malloc(sizeof(char) * (2+strlen(paths[i].path))),
150 S_IFDIR | S_IREAD | S_IEXEC | ((S_IREAD | S_IEXEC)>>3),
151 st.st_uid,st.st_gid);
152 if (ctlfs->ctlfs[i].path == NULL) {
153 free_ctlnode(ctlfs->ctlfs);
154 dbg(("\nctl out of mem"));
155 return(-1);
156 }
157 sprintf(ctlfs->ctlfs[i].path,"%s",paths[i].path);
158 dbg(("\nctl: path=%s, path2=%s ino=%d",paths[i].path, ctlfs->ctlfs[i].path, ctlfs->ctlfs[i].attr.st_ino));
159
160 // replica subdir
161 ctlfs->ctlfs[i].ctlfs = malloc(sizeof(ctlfs_entry_t)*3);
162 if (ctlfs->ctlfs[i].ctlfs==NULL) {
163 free_ctlnode(ctlfs->ctlfs);
164 return(-1);
165 }
166 // end of the list
167 ctlfs->ctlfs[i].ctlfs[2].path = NULL;
168 // status file
169 ctlfs->ctlfs[i].ctlfs[0] = mkstatnod(malloc(sizeof(char) * (2+strlen(status_fname))),
170 S_IFREG | S_IREAD | S_IWRITE | ((S_IREAD | S_IWRITE)>>3),
171 st.st_uid,st.st_gid);
172 if (ctlfs->ctlfs[i].ctlfs[0].path == NULL) {
173 free_ctlnode(ctlfs->ctlfs);
174 dbg(("\nctl out of mem"));
175 return(-1);
176 }
177 sprintf(ctlfs->ctlfs[i].ctlfs[0].path,status_fname);
178 dbg(("\nctl: status ino=%d",ctlfs->ctlfs[i].ctlfs[0].attr.st_ino));
179 // nagios plugin script
180 ctlfs->ctlfs[i].ctlfs[1] = mkstatnod(malloc(sizeof(char) * (2+strlen(nagios_fname))),
181 S_IFREG | S_IREAD | S_IEXEC | ((S_IREAD | S_IEXEC)>>3),
182 st.st_uid,st.st_gid);
183 if (ctlfs->ctlfs[i].ctlfs[1].path == NULL) {
184 free_ctlnode(ctlfs->ctlfs);
185 dbg(("\nctl out of mem"));
186 return(-1);
187 }
188 ctlfs->ctlfs[i].ctlfs[1].attr.st_size = strlen(nagios_script);
189 sprintf(ctlfs->ctlfs[i].ctlfs[1].path,nagios_fname);
190 dbg(("\nctl: status ino=%d",ctlfs->ctlfs[i].ctlfs[1].attr.st_ino));
191 }
192 ctlfs->ctlfs[i].path = NULL;
193
194 return(0);
195 }
196
197 ctlfs_search_t find_path(const char *path, ctlfs_entry_t *c, int deep)
198 {
199 ctlfs_search_t res;
200 size_t s;
201 int i;
202
203 for(i=0;c[i].path!=NULL;++i) {
204 if (!strcmp(path,c[i].path)) {
205 res.ctlfs = c;
206 res.i = i;
207 return(res);
208 }
209 s = strlen(c[i].path);
210 if ((!strncmp(path,c[i].path,s)) && (path[s]=='/') && (c[i].ctlfs!=NULL)) {
211 if (!deep) {
212 res.ctlfs = c;
213 res.i = i;
214 return(res);
215 }
216 return(find_path(path+s, c[i].ctlfs,deep-1));
217 }
218 }
219 res.ctlfs = NULL;
220 res.i = 0;
221 return(res);
222 }
223
224 char *get_daddy(const char *path)
225 {
226 char *s, *p;
227
228 if (path[1]=='\0') {
229 s = strdup("");
230 return(s);
231 }
232 s = strdup(path);
233 if (s==NULL) {
234 return(s);
235 }
236 p = strrchr(s,'/');
237 if (p==s) {
238 s[1] = '\0';
239 } else {
240 (*p) = '\0';
241 }
242 return(s);
243 }
244
245 ////////////////////////////////////////////////////////////////////////////
246 ////////////////////////////////////////////////////////////////////////////
247 //
248 //
249 // P E R M I S S I O N C H E C K F U N C T I O N S
250 //
251 //
252 ////////////////////////////////////////////////////////////////////////////
253 ////////////////////////////////////////////////////////////////////////////
254
255 int get_perm(uid_t uid, gid_t gid, struct stat st)
256 {
257 int i, res=0;
258 char *buffer;
259 struct group result_buf, *result=NULL;
260 struct passwd *pw;
261 char **member;
262 dbg(("\ncuid:%d\tstuid:%d",uid,st.st_uid));
263 if (uid==st.st_uid) {
264 return((st.st_mode&0700) >> 6);
265 }
266 if (gid==st.st_gid) {
267 return((st.st_mode&070) >> 3);
268 }
269 i = 1024;
270 do {
271 buffer = calloc(i,sizeof(char));
272 if (buffer!=NULL) {
273 res = getgrgid_r(st.st_gid,&result_buf,buffer,i,&result);
274 if (res==ERANGE) {
275 free(buffer);
276 i <<= 1;
277 }
278 }
279 } while ((res==ERANGE) && (buffer!=NULL));
280 if (buffer==NULL) {
281 errno = ENOMEM;
282 return(-1);
283 }
284 if (result!=NULL) {
285 member = result->gr_mem;
286 while (*member) {
287 pw = getpwnam(*member);
288 if (pw->pw_uid==uid) {
289 free(buffer);
290 return((st.st_mode&070) >> 3);
291 }
292 member++;
293 }
294 }
295 free(buffer);
296 return(st.st_mode&7);
297 }
298
299 int get_path_perm(const char *path)
300 {
301 ctlfs_search_t res, path_res;
302
303 static struct fuse_context *context;
304 int perm, path_perm;
305
306 context = fuse_get_context();
307
308 if ((!context->uid) || (!context->gid)) {
309 return(7);
310 }
311
312 perm = get_perm(context->uid,context->gid,ctlfs[0].attr);
313
314 if (path[1]=='\0') {
315 dbg(("\nperm (/):%d",perm));
316 return(perm);
317 }
318
319 if (perm&1) {
320 path_perm = perm;
321
322 res = find_path(path,ctlfs->ctlfs,0);
323 if (res.ctlfs==NULL) {
324 return(-ENOENT);
325 }
326 perm = get_perm(context->uid,context->gid,res.ctlfs->attr);
327 path_res = res;
328
329 res = find_path(path,ctlfs->ctlfs,1);
330 if ((res.ctlfs==path_res.ctlfs) && (res.i==path_res.i)) {
331 dbg(("\nperm:%d",perm));
332 return(perm);
333 }
334 if (perm&1) {
335 perm = get_perm(context->uid,context->gid,res.ctlfs->attr);
336 dbg(("\nperm:%d",perm));
337 return(perm);
338 }
339 }
340 return(0);
341 }
342
343
344 ////////////////////////////////////////////////////////////////////////////
345 ////////////////////////////////////////////////////////////////////////////
346 //
347 //
348 // W R A P P E R F U N C T I O N S
349 //
350 //
351 ////////////////////////////////////////////////////////////////////////////
352 ////////////////////////////////////////////////////////////////////////////
353
354
355 static int chironctl_statfs(const char *path, struct statvfs *stbuf)
356 {
357 (void) path;
358 stbuf->f_bsize = 4096;
359 stbuf->f_frsize = 4096;
360 stbuf->f_bsize = 4096;
361 stbuf->f_frsize = 4096;
362 stbuf->f_blocks = 0xFFFFF;
363 stbuf->f_bfree = 0xFFFFF;
364 stbuf->f_bavail = 0xFFFFF;
365 stbuf->f_files = 0xFFFF;
366 stbuf->f_ffree = 0xFFFF;
367 stbuf->f_favail = 0xFFFF;
368 stbuf->f_fsid = -1047;
369 stbuf->f_flag = 1024;
370 stbuf->f_namemax= 255;
371 return(0);
372 }
373
374
375 static int chironctl_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
376 off_t offset, struct fuse_file_info *fi)
377 {
378 ctlfs_entry_t *dir;
379 ctlfs_search_t res;
380
381 (void) offset;
382 (void) fi;
383 dbg(("\nctlreaddir: %s, offset: %ld\n",path,offset));
384 if ((get_path_perm(path)&5)!=5) {
385 return(-EACCES);
386 }
387
388 if (path[1]=='\0') {
389 dir = ctlfs;
390 } else {
391 res = find_path(path,ctlfs->ctlfs,-1);
392 if (res.ctlfs==NULL) {
393 return(-ENOENT);
394 }
395 dir = res.ctlfs+res.i;
396 }
397 filler(buf, ".", &(dir->attr), 0);
398 // lstat(chironctl_parentdir,&st);
399 // filler(buf, "..", &st, 0);
400 for(dir = dir->ctlfs;dir->path!=NULL;++dir) {
401 if (filler(buf, dir->path+1, &(dir->attr), 0)) {
402 // dbg(("\nctlreaddir: i=%d\n",i));
403 return 0;
404 }
405 }
406 return 0;
407 }
408
409 static void chironctl_destroy(void *notused)
410 {
411 (void) notused;
412 }
413
414 static int chironctl_truncate(const char *path_orig, off_t size)
415 {
416 dbg(("\ntruncate: %s\n",path_orig));
417 (void) path_orig;
418 (void) size;
419 return(0);
420 }
421
422 static int chironctl_getattr(const char *path, struct stat *stbuf)
423 {
424 dbg(("\nctlgetattr: %s\n",path));
425 ctlfs_entry_t *dir;
426 ctlfs_search_t res;
427 char *p;
428 int perm;
429
430 p = get_daddy(path);
431 if (p==NULL) {
432 return(-ENOMEM);
433 }
434 dbg(("\nctlgetattr-daddy: %s\n",p));
435
436 if (p[0]) {
437 perm = get_path_perm(p);
438 dbg(("\nctlgetattr-perm: %d\n",perm));
439 if ((perm&5)!=5) {
440 return(-EACCES);
441 }
442 } else {
443 if ((get_path_perm(path)&5)!=5) {
444 return(-EACCES);
445 }
446 }
447
448 dbg(("\nctlgetattr-perm: ok, path=%s\n",path));
449
450 if (path[1]=='\0') {
451 dir = ctlfs;
452 } else {
453 res = find_path(path,ctlfs->ctlfs,-1);
454 if (res.ctlfs==NULL) {
455 dbg(("\nctlgetattr-404: notfound\n"));
456 return(-ENOENT);
457 }
458 dir = res.ctlfs+res.i;
459 }
460 dbg(("\nctlgetattr: mode=%o\n",dir->attr.st_mode));
461
462 memcpy(stbuf, &(dir->attr), sizeof(struct stat));
463 return(0);
464 }
465
466 static int chironctl_open(const char *path, struct fuse_file_info *fi)
467 {
468 int perm = 0, perm_mask = 0;
469 ctlfs_search_t res;
470 (void) fi;
471
472 if (fi->flags&O_CREAT) {
473 return(-EACCES);
474 }
475
476 if (fi->flags&(O_WRONLY|O_TRUNC|O_APPEND)) {
477 perm_mask = 2;
478 } else if (fi->flags&O_RDWR) {
479 perm_mask = 6;
480 } else if ((fi->flags&(O_RDONLY|O_EXCL)) == (O_RDONLY)) {
481 perm_mask = 4;
482 }
483 perm = get_path_perm(path);
484 if (((perm&perm_mask)!=perm_mask) || (!perm_mask) || (!perm)) {
485 return(-EACCES);
486 }
487
488 if (path[1]!='\0') {
489 res = find_path(path,ctlfs->ctlfs,-1);
490 if (res.ctlfs==NULL) {
491 return(-ENOENT);
492 }
493 }
494 return 0;
495 }
496
497 static int chironctl_read(const char *path, char *buf, size_t size, off_t offset,
498 struct fuse_file_info *fi)
499 {
500 int sz, rep, someerr, fname;
501 ctlfs_search_t res;
502 ctlfs_entry_t *cmd;
503 char *chbuf = NULL;
504
505 (void) fi;
506
507 if ((get_path_perm(path)&4)!=4) {
508 return(-EACCES);
509 }
510
511 if (path[1]=='\0') {
512 return(-ENOSYS);
513 }
514 res = find_path(path,ctlfs->ctlfs,-1);
515 if (res.ctlfs==NULL) {
516 return(-ENOENT);
517 }
518 cmd = res.ctlfs+res.i;
519
520 res = find_path(path,ctlfs->ctlfs,0);
521 rep = res.i;
522 dbg(("\nctlread: rep: %d, cmd: %s\n",rep,cmd->path));
523 fname = (!strcmp(cmd->path,status_fname))
524 ? 1
525 : (
526 (!strcmp(cmd->path,nagios_fname))
527 ? 2
528 : 0
529 );
530 if (fname) {
531 pthread_mutex_lock(&comm);
532
533 fprintf(tochironfs,"0007stat:%02X",res.i);
534 fflush(tochironfs);
535 someerr = read_a_line(&chbuf,&sz,fromchironfs);
536 pthread_mutex_unlock(&comm);
537 if (someerr) {
538 return (-EIO);
539 }
540 dbg(("\nctlread: rep: %d, cmd: %s=%s\n",rep,cmd->path,chbuf));
541
542 if (fname==1) {
543 sprintf(buf,"%c",chbuf[0]);
544 free(chbuf);
545 return(1);
546 }
547 if (fname==2) {
548 sz = strlen(nagios_script) - offset;
549 if (sz<0) {
550 sz = 0;
551 }
552 sz = min(sz,(int)size);
553
554 memcpy(nagios_script+538,status_msgs[chbuf[0]-'0'],strlen(status_msgs[chbuf[0]-'0']));
555 nagios_script[602] = chbuf[0];
556 memcpy(buf,nagios_script+offset,sz);
557 free(chbuf);
558 return(sz);
559 }
560 }
561
562 return(-ENOSYS);
563 }
564
565 static int chironctl_write(const char *path, const char *buf, size_t size,
566 off_t offset, struct fuse_file_info *fi)
567 {
568 int sz, rep, someerr;
569 ctlfs_search_t res;
570 ctlfs_entry_t *cmd;
571 char *chbuf = NULL;
572
573 (void) fi;
574 (void) offset;
575 dbg(("\nctlwrite: %d=%s\n",size,buf));
576 if ((get_path_perm(path)&2)!=2) {
577 return(-EACCES);
578 }
579
580 if (path[1]=='\0') {
581 return(-ENOSYS);
582 }
583 res = find_path(path,ctlfs->ctlfs,-1);
584 if (res.ctlfs==NULL) {
585 return(-ENOENT);
586 }
587 cmd = res.ctlfs+res.i;
588
589 res = find_path(path,ctlfs->ctlfs,0);
590 rep = res.i;
591
592 if (!strcmp(cmd->path,status_fname)) {
593 if ((size>2)
594 || ((size==2) && (buf[1]!='\n'))
595 // || ((buf[0]!='0') && (buf[0]!='1') && (buf[0]!='2'))
596 || ((buf[0]!='0') && (buf[0]!='2'))
597 ) {
598 return(-ENOSYS);
599 }
600 pthread_mutex_lock(&comm);
601
602 if (buf[0]=='0') {
603 fprintf(tochironfs,"0008trust:%02X",res.i);
604 } else if (buf[0]=='1') {
605 fprintf(tochironfs,"0009enable:%02X",res.i);
606 } else if (buf[0]=='2') {
607 fprintf(tochironfs,"000Adisable:%02X",res.i);
608 }
609 fflush(tochironfs);
610 someerr = read_a_line(&chbuf,&sz,fromchironfs);
611 pthread_mutex_unlock(&comm);
612 if (someerr) {
613 return (-EIO);
614 }
615 dbg(("\nctlwrite: rep: %d, cmd: %s=%s\n",rep,cmd->path,chbuf));
616
617 if ((chbuf[0]=='O') && (chbuf[1]=='K')) {
618 free(chbuf);
619 return(size);
620 }
621 free(chbuf);
622 return(-EIO);
623 }
624
625 return(-ENOSYS);
626 }
627
628 struct fuse_operations chironctl_oper = {
629 .readdir = chironctl_readdir,
630 .statfs = chironctl_statfs,
631 .destroy = chironctl_destroy,
632 .getattr = chironctl_getattr,
633 .open = chironctl_open,
634 .read = chironctl_read,
635 .write = chironctl_write,
636 .truncate = chironctl_truncate,
637 };
638
639
640 void free_vars(void)
641 {
642 int i;
643 if (chironctl_parentdir!=NULL) {
644 free(chironctl_parentdir);
645 }
646 if (chironctl_mountpoint!=NULL) {
647 free(chironctl_mountpoint);
648 }
649 if (mount_point!=NULL) {
650 free(mount_point);
651 }
652 if (paths!=NULL) {
653 for(i=0;i<max_replica;++i) {
654 if (paths[i].path != NULL) {
655 free(paths[i].path);
656 }
657 }
658 free(paths);
659 }
660 }
661
662 int main(int argc, char *argv[])
663 {
664 int res, sz, someerr, i, j, l;
665 char *buf= NULL, *ptr;
666 char *fuse_argv[4];
667
668 (void) argc;
669 dbg(("chironctl: started"));
670 printf("0004info");
671 fflush(stdout);
672 someerr = read_a_line(&buf,&sz,stdin);
673 if (someerr) {
674 exit(-1);
675 }
676 dbg(("chironfs mnt: %s",buf));
677 mount_point = strdup(buf);
678 if (mount_point==NULL) {
679 dbg(("no mem"));
680 free(buf);
681 exit(-1);
682 }
683 someerr = read_a_line(&buf,&sz,stdin);
684 if (someerr) {
685 free_vars();
686 exit(-1);
687 }
688 dbg(("chironctl mnt: %s",buf));
689 chironctl_mountpoint = strdup(buf);
690 if (chironctl_mountpoint==NULL) {
691 dbg(("no mem"));
692 free(buf);
693 free_vars();
694 exit(-1);
695 }
696
697 ptr = strrchr(chironctl_mountpoint,'/');
698 if (ptr==chironctl_mountpoint) {
699 chironctl_parentdir = strdup("/");
700 } else {
701 chironctl_parentdir = malloc(sizeof(char) * ((ptr-chironctl_mountpoint)+1));
702 if (chironctl_parentdir!=NULL) {
703 strncpy(chironctl_parentdir,chironctl_mountpoint,ptr-chironctl_mountpoint);
704 }
705 }
706 if (chironctl_parentdir==NULL) {
707 free(buf);
708 free_vars();
709 exit(-1);
710 }
711
712 someerr = read_a_line(&buf,&sz,stdin);
713 if (someerr) {
714 free_vars();
715 exit(-1);
716 }
717 sscanf(buf,"%X",&max_replica);
718 dbg(("max-replica: %s (%d)",buf,max_replica));
719 paths = malloc(sizeof(path_t)*max_replica);
720 if (paths==NULL) {
721 dbg(("no mem"));
722 free(buf);
723 free_vars();
724 exit(-1);
725 }
726 for(i=0;i<max_replica;++i) {
727 paths[i].path = NULL;
728 }
729 for(i=0;i<max_replica;++i) {
730 someerr = read_a_line(&buf,&sz,stdin);
731 if (someerr) {
732 free_vars();
733 exit(-1);
734 }
735 dbg(("replica: %s",buf));
736 paths[i].path = malloc(sizeof(char) * strlen(buf) + 2);
737 if (paths[i].path==NULL) {
738 dbg(("no mem"));
739 free(buf);
740 free_vars();
741 exit(-1);
742 }
743 paths[i].path[0]='/';
744 for(l=strlen(buf),j=0;j<l;++j) {
745 if (buf[j]=='/') {
746 paths[i].path[j+1] = '_';
747 } else {
748 paths[i].path[j+1] = buf[j];
749 }
750 }
751 }
752
753 if ((res = mkctlfs())) {
754 dbg(("%s",buf));
755 free(buf);
756 free_vars();
757 exit(-res);
758 }
759
760 fromchironfs = fdopen(STDIN_FILENO,"r");
761 tochironfs = fdopen(STDOUT_FILENO,"a");
762 close(STDERR_FILENO);
763
764 fuse_argv[0] = argv[0];
765 fuse_argv[1] = chironctl_mountpoint;
766 fuse_argv[2] = fuse_options;
767 fuse_argv[3] = NULL;
768 dbg(("starting fuse"));
769 res = fuse_main(3, fuse_argv, &chironctl_oper);
770 dbg(("ending fuse: %d", res));
771 free(buf);
772 free_vars();
773 return(res);
774 }
775