(no commit message)
[vsys-wrappers.git] / fuse / reroutemount.c
1 #include <assert.h>
2 #include <errno.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <sys/socket.h>
6 #include <sys/un.h>
7 #include "fdpass.h"
8
9 char *socket_name = "/vsys/fd_fusemount.control";
10 unsigned int arg_length = 128;
11
12 void send_argument(int control_channel_fd, const char *source) {
13     int sent;
14     sent=send(control_channel_fd, source, arg_length, 0);
15     if (sent<arg_length) {
16         printf("Error receiving arguments over the control buffer\n");
17         exit(1);
18     }
19 }
20
21 int connect_socket() {
22   int fd = socket( AF_UNIX, SOCK_STREAM, 0 );
23   struct sockaddr_un addr;
24   addr.sun_family = AF_UNIX;
25   strcpy( addr.sun_path, socket_name );
26   int len = strlen(socket_name) + sizeof(addr.sun_family);
27   assert( connect( fd, (struct sockaddr *) &addr, len ) == 0 );
28   return fd;
29 }
30
31 int get_magic_fd (char *data) {
32     char *ptr;
33     int fd;
34
35     data[arg_length-1]='\0';
36     ptr = strstr(data,"fd=");
37     if (!ptr)
38         return -1;
39
40     // Found two fd= expressions
41     if (strstr(ptr+3,"fd="))
42         return -1;
43
44     if (*(ptr+3)!='\0') {
45         sscanf(ptr+3,"%d",&fd);
46         return fd;
47     }
48     else
49         return -1;
50 }
51
52 int mount(const char *source, const char *target, const char *filesystemtype,
53         unsigned long mountflags, const void *data) {
54   int fd = connect_socket();
55   int old_fuse_fd, new_fuse_fd;
56
57   char buf[1024];
58
59   send_argument(fd, source);
60   send_argument(fd, target );
61   send_argument(fd, filesystemtype );
62   send_argument(fd, data );
63
64   old_fuse_fd = get_magic_fd (data);
65
66
67   if (old_fuse_fd == -1) {
68       printf ("Reroutemount: Could not identify FUSE fd: %d\n", old_fuse_fd);
69       exit(1);
70   }
71
72   send_fd(fd, old_fuse_fd);
73   new_fuse_fd=receive_fd(fd);
74
75   if (new_fuse_fd == -1) {
76       printf ("Reroutemount: Fusemount returned bad fd: %d\n", new_fuse_fd);
77       exit(1);
78   }
79
80   if( dup2(new_fuse_fd, old_fuse_fd ) != new_fuse_fd ) {
81       printf ("Could not duplicate returned file descriptor\n");
82       exit(1);
83   }
84
85   close(fd);
86   return 0;
87
88 }