Fixed some bugs, and tested to work.
[vsys-scripts.git] / fd_fusemount.c
1 #include <sys/types.h>
2 #include <sys/socket.h>
3 #include <sys/mount.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8 #include "fdpass.h"
9
10 unsigned int rcvbuf = 16*1024*1024;
11 unsigned int arg_length = 128;
12 unsigned int mountflags = MS_NODEV | MS_NOSUID;
13
14 void receive_argument(int control_channel_fd, char *source) {
15     int received;
16     received=recv(control_channel_fd, source, arg_length, 0);
17     if (received<arg_length) {
18         printf("Error receiving arguments over the control buffer\n");
19         exit(1);
20     }
21 }
22
23 int set_magic_fd (char *data, int new_fd) {
24     char *ptr;
25     int fd;
26
27     data[arg_length-1]='\0';
28     ptr = strstr(data,"fd=");
29     if (!ptr)
30         return -1;
31
32     // Found two fd= expressions
33     if (strstr(ptr+3,"fd="))
34         return -1;
35
36     if (*(ptr+3)!='\0') {
37         char *new_data = (char *) malloc(arg_length);
38         char *head = (char *) malloc(arg_length);
39         char *tail = (char *) malloc(arg_length);
40         sscanf(ptr+3,"%d",&fd);
41         strncpy(head, data, ptr - data);
42         tail = strchr(ptr+3,',');
43         sprintf(new_data,"%sfd=%d,%s",head,new_fd,tail);
44         strcpy(data,new_data);
45         free(new_data);
46         free(head);
47         free(tail);
48         return fd;
49     }
50     else
51         return -1;
52 }
53
54 void check_source(char *source) {
55     source[arg_length-1]='\0';
56     if (strchr(source,'/') || strstr(source,"..")) {
57         printf("Tried mounting with source = %s\n", source);
58         exit(1);
59     }
60 }
61
62 void check_target(char *target) {
63     target[arg_length-1]='\0';
64     if (strstr(target,"..")) {
65         printf("Tried mounting with target = %s\n", target);
66         exit(1);
67     }
68 }
69
70 void check_fstype(char *filesystemtype) {
71     if (strncmp(filesystemtype,"fuse",4)) {
72         printf("Tried mounting filesystem type %s\n", filesystemtype);
73     }
74 }
75
76 int main(int argc, char *argv[]) {
77     int control_channel_fd, magic_fd, mount_fd;
78     char source[128],target[128],filesystemtype[128],data[128],slice_target[256];
79
80     int received;
81
82     if (argc < 3) {
83         printf("This script is called by vsys.\n");
84         exit(1);
85     }
86
87     char *slice_name = argv[1];
88     
89     sscanf(argv[2],"%d", &control_channel_fd);
90
91     if (control_channel_fd <3 || control_channel_fd > 1023) {
92         printf ("Got control_channel_fd = %d\n", control_channel_fd);
93         exit(1);
94     }
95
96     receive_argument(control_channel_fd, source);
97     receive_argument(control_channel_fd, target);
98     receive_argument(control_channel_fd, filesystemtype);
99     receive_argument(control_channel_fd, data);
100
101     mount_fd = receive_fd (control_channel_fd);
102
103     if (mount_fd < 2) {
104         printf("mount_fd = %d\n", mount_fd);
105         exit(1);
106     }
107
108     set_magic_fd(data, mount_fd);
109
110
111     check_source(source);
112     check_target(target);
113     check_fstype(filesystemtype);
114
115     sprintf(slice_target,"/vservers/%s/%s", target);
116
117     if (!mount(source, slice_target, filesystemtype, mountflags, data)) {
118         send_fd(control_channel_fd, mount_fd);
119     }
120     else {
121         printf ("Error executing mount\n");
122         exit(1);
123     }
124
125     return 0;
126 }