1a1fc7be57fb2cf311a0126e4c71af6ccdd6f3ca
[tpg/acess2.git] / Usermode / Applications / mount_src / main.c
1 /*
2  * Acess2 mount command
3  */
4 #include <acess/sys.h>
5 #include <stdlib.h>
6 #include <stdio.h>
7
8 #define MOUNTABLE_FILE  "/Acess/Conf/Mountable"
9 #define MOUNTED_FILE    "/Devices/system/VFS/Mounts"
10
11 // === PROTOTYPES ===
12 void    ShowUsage(char *ProgName);
13  int    GetMountDefs(char *Ident, char **spDevice, char **spDir, char **spType, char **spOptions);
14
15 // === CODE ===
16 /**
17  * \fn int main(int argc, char *argv[])
18  * \brief Entrypoint
19  */
20 int main(int argc, char *argv[])
21 {
22          int    fd;
23          int    i;
24         char    *arg;
25         
26         char    *sType = NULL;
27         char    *sDevice = NULL;
28         char    *sDir = NULL;
29         char    *sOptions = NULL;
30          int    bUnmount = 0;
31
32         // List mounted filesystems
33         // - This is cheating, isn't it?
34         if(argc == 1) {
35                 // Dump the contents of /Devices/system/VFS/Mounts
36                 FILE    *fp = fopen(MOUNTED_FILE, "r");
37                 char    buf[1024];
38                  int    len;
39                 while( (len = fread(buf, 1024, 1, fp)) )
40                         fwrite(buf, len, 1, stdout);
41                 printf("\n");
42                 return 0;
43         }
44
45         if(argc < 3) {
46                 ShowUsage(argv[0]);
47                 return EXIT_FAILURE;
48         }
49         
50         // Parse Arguments
51         for( i = 1; i < argc; i++ )
52         {
53                 arg = argv[i];
54                 
55                 if(arg[0] == '-')
56                 {
57                         switch(arg[1])
58                         {
59                         // -t <driver> :: Filesystem driver to use
60                         case 't':       sType = argv[++i];      break;
61                         // -o option_list :: Options to pass the driver
62                         case 'o':       sOptions = argv[++i];   break;
63                         // -u :: Unmount
64                         case 'u':       bUnmount = 1;   break;
65                         case '-':
66                                 //TODO: Long Arguments
67                         default:
68                                 ShowUsage(argv[0]);
69                                 return EXIT_FAILURE;
70                         }
71                         continue;
72                 }
73                 
74                 // Device?
75                 if(sDevice == NULL) {
76                         sDevice = arg;
77                         continue;
78                 }
79                 
80                 // Directory?
81                 if(sDir == NULL) {
82                         sDir = arg;
83                         continue;
84                 }
85                 
86                 ShowUsage(argv[0]);
87                 return EXIT_FAILURE;
88         }
89
90         if( bUnmount )
91         {
92                 // TODO: Check for a match in the fstab
93                 
94                 if( sDir ) {
95                         fprintf(stderr, "`mount -u` takes one argument\n");
96                 }
97                 
98                 sDir = sDevice;
99                 if( _SysMount(NULL, sDir, NULL, NULL) ) // Unmount (Dev=NULL means unmount)
100                 {
101                         fprintf(stderr, "Unmount failed\n");
102                 }
103                 return EXIT_SUCCESS;
104         }
105
106         // Check if we even got a device/mountpoint
107         if(sDevice == NULL) {
108                 ShowUsage(argv[0]);
109                 return EXIT_FAILURE;
110         }
111
112         // If no directory was passed (we want to use the mount list)
113         // or we are not root (we need to use the mount list)
114         // Check the mount list
115         if(sDir == NULL || getuid() != 0)
116         {
117                 // Check if it is defined in the mounts file
118                 // - At this point sDevice could be a device name or a mount point
119                 if(GetMountDefs(sDevice, &sDevice, &sDir, &sType, &sOptions) == 0)
120                 {
121                         if(sDir == NULL)
122                                 fprintf(stderr, "Unable to find '%s' in '%s'\n",
123                                         sDevice, MOUNTABLE_FILE
124                                         );
125                         else
126                                 fprintf(stderr, "You must be root to mount devices or directories not in '%s'\n",
127                                         MOUNTABLE_FILE
128                                         );
129                         return EXIT_FAILURE;
130                 }
131         
132                 // We need to be root to mount a filesystem, so, let us be elevated!
133                 setuid(0);      // I hope I have the setuid bit implemented.
134         }
135         else
136         {
137                 // Check that we were passed a filesystem type
138 //              if(sType == NULL) {
139 //                      fprintf(stderr, "Please pass a filesystem type\n");
140 //                      return EXIT_FAILURE;
141 //              }
142         }
143         
144         // Check Device
145         fd = _SysOpen(sDevice, OPENFLAG_READ);
146         if(fd == -1) {
147                 printf("Device '%s' cannot be opened for reading\n", sDevice);
148                 return EXIT_FAILURE;
149         }
150         _SysClose(fd);
151         
152         // Check Mount Point
153         fd = _SysOpen(sDir, OPENFLAG_EXEC);
154         if(fd == -1) {
155                 printf("Directory '%s' does not exist\n", sDir);
156                 return EXIT_FAILURE;
157         }
158         _SysClose(fd);
159
160         // Replace sOptions with an empty string if it is still NULL
161         if(sOptions == NULL)    sOptions = "";
162
163         // Let's Mount!
164         if( _SysMount(sDevice, sDir, sType, sOptions) ) {
165 //              perror("_SysMount");
166                 if( !sType )
167                         fprintf(stderr, "Filesystem autodetection failed, please pass a type\n");
168                 else {
169                         fprintf(stderr, "Mount %s:'%s'=>'%s' failed\n", sType, sDevice, sDir);
170                 }
171         }
172
173         return 0;
174 }
175
176 void ShowUsage(char *ProgName)
177 {
178         fprintf(stderr, "Usage:\n");
179         fprintf(stderr, "    %s [-t <type>] <device> <directory> [-o <options>]\n", ProgName);
180         fprintf(stderr, "or  %s <device>\n", ProgName);
181         fprintf(stderr, "or  %s <directory>\n", ProgName);
182         fprintf(stderr, "or  %s\n", ProgName);
183 }
184
185 /**
186  * \fn int GetMountDefs(char *Ident, char **spDevice, char **spDir, char **spType, char **spOptions)
187  * \brief Reads the mountable definitions file and returns the corresponding entry
188  * \param spDevice      Pointer to a string (pointer) determining the device (also is the input for this function)
189  * \note STUB
190  */
191 int GetMountDefs(char *Ident, char **spDevice, char **spDir, char **spType, char **spOptions)
192 {
193         // TODO: Read the mounts file (after deciding what it will be)
194         return 0;
195 }

UCC git Repository :: git.ucc.asn.au