This repository is to contain libraries that will let privilege-demanding application...
[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 "stolen_from_fuse.h"
8
9 char *socket_name = "/vsys/local_fusemount.control";
10
11 int rrm_connect_socket() {
12   int fd = socket( AF_UNIX, SOCK_STREAM, 0 );
13   struct sockaddr_un addr;
14   addr.sun_family = AF_UNIX;
15   strcpy( addr.sun_path, socket_name );
16   int len = strlen(socket_name) + sizeof(addr.sun_family);
17   assert( connect( fd, (struct sockaddr *) &addr, len ) == 0 );
18   return fd;
19 }
20
21 void rrm_do_umount( char *const argv[], int n, int fd ) {
22
23   // write the length
24   char buf[1024];
25   sprintf( buf, "%08x\n", n );
26   write( fd, buf, strlen(buf) );
27
28   // now write each arg
29   int i;
30   for( i = 0; i < n; i++ ) {
31     assert( strlen(argv[i]) < 1024 );
32     sprintf( buf, "%s\n", argv[i] );
33     write( fd, buf, strlen(buf) );
34   }
35
36   char inbuf[10];
37   int n2 = read( fd, inbuf, 10 );
38   inbuf[n2] = '\0';
39
40   int r = atoi(inbuf);
41
42 }
43
44 int umount2( const char *mnt, int flags ) {
45  
46   int fd = rrm_connect_socket();
47
48   const char *argv[3];
49   argv[0] = "fusermount";
50   argv[1] = "-u";
51   argv[2] = mnt;
52
53   rrm_do_umount( (char **const) argv, 3, fd );
54
55   close(fd);
56  
57 }
58
59 int mount(const char *source, const char *target, const char *filesystemtype,
60         unsigned long mountflags, const void *data) {
61
62   int fd = rrm_connect_socket();
63   
64   char buf[1024];
65   sprintf( buf, "%08x\n", 0 );
66   write( fd, buf, strlen(buf) );
67
68   sprintf( buf, "%s\n%s\n%s\n%ld\n%s\n", source, target, filesystemtype,
69            mountflags, data );
70   write( fd, buf, strlen(buf) );
71
72   char inbuf[10];
73   int n = read( fd, inbuf, 9 );
74   inbuf[n] = '\0';
75
76   int r;
77   assert( sscanf( inbuf, "%08x\n", &r ) == 1);
78
79   int fuse_fd = 0;
80   if( r < 0 ) {
81     errno = r;
82     return -1;
83   } else if( r > 0 ) {
84     // get the fd
85     fuse_fd = rrm_receive_fd(fd);
86
87     // what was the old fd?
88     int old_fd;
89     char extra[1024];
90     int s = sscanf( data, "fd=%d,%s", &old_fd, extra );
91     assert( dup2( fuse_fd, old_fd ) == old_fd );
92
93   }
94
95   close(fd);
96   return 0;
97
98 }
99
100 int execv( const char *path, char *const argv[] ) {
101
102   if( strstr( path, "fusermount" ) == NULL ) {
103     return execv( path, argv );
104   }
105
106   // also make sure this is an unmount . . .
107   int n = 0;
108   char *arg = argv[n];
109   int found_u = 0;
110   while( arg != NULL ) {
111     if( strcmp( arg, "-u" ) == 0 ) {
112       found_u = 1;
113       break;
114     }
115     arg = argv[++n];
116   }
117
118   if( !found_u ) {
119     return execv( path, argv );
120   }
121
122   // Have root do any fusermounts we need done
123   int fd = rrm_connect_socket();
124
125   rrm_do_umount( argv, n, fd );
126
127   exit(0);
128
129 }
130