602aefd439fd527ce3c8e19fc52e58c3afea5b76
[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         char    *sType = NULL;
26         char    *sDevice = NULL;
27         char    *sDir = NULL;
28         char    *sOptions = NULL;
29
30         // List mounted filesystems
31         // - This is cheating, isn't it?
32         if(argc == 1) {
33                 // Dump the contents of /Devices/system/VFS/Mounts
34                 FILE    *fp = fopen("/Devices/system/VFS/Mounts", "r");
35                 char    buf[1024];
36                  int    len;
37                 while( (len = fread(buf, 1024, 1, fp)) )
38                         fwrite(buf, len, 1, stdout);
39                 printf("\n");
40                 return 0;
41         }
42
43         if(argc < 3) {
44                 ShowUsage(argv[0]);
45                 return EXIT_FAILURE;
46         }
47         
48         // Parse Arguments
49         for( i = 1; i < argc; i++ )
50         {
51                 arg = argv[i];
52                 
53                 if(arg[0] == '-')
54                 {
55                         switch(arg[1])
56                         {
57                         // -t <driver> :: Filesystem driver to use
58                         case 't':       sType = argv[++i];      break;
59                         case 'o':       sOptions = argv[++i];   break;
60                         case '-':
61                                 //TODO: Long Arguments
62                         default:
63                                 ShowUsage(argv[0]);
64                                 return EXIT_FAILURE;
65                         }
66                         continue;
67                 }
68                 
69                 // Device?
70                 if(sDevice == NULL) {
71                         sDevice = arg;
72                         continue;
73                 }
74                 
75                 // Directory?
76                 if(sDir == NULL) {
77                         sDir = arg;
78                         continue;
79                 }
80                 
81                 ShowUsage(argv[0]);
82                 return EXIT_FAILURE;
83         }
84
85         // Check if we even got a device/mountpoint
86         if(sDevice == NULL) {
87                 ShowUsage(argv[0]);
88                 return EXIT_FAILURE;
89         }
90
91         // If no directory was passed (we want to use the mount list)
92         // or we are not root (we need to use the mount list)
93         // Check the mount list
94         if(sDir == NULL || getuid() != 0)
95         {
96                 // Check if it is defined in the mounts file
97                 // - At this point sDevice could be a device name or a mount point
98                 if(GetMountDefs(sDevice, &sDevice, &sDir, &sType, &sOptions) == 0)
99                 {
100                         if(sDir == NULL)
101                                 fprintf(stderr, "Unable to find '%s' in '%s'\n",
102                                         sDevice, MOUNTABLE_FILE
103                                         );
104                         else
105                                 fprintf(stderr, "You must be root to mount devices or directories not in '%s'\n",
106                                         MOUNTABLE_FILE
107                                         );
108                         return EXIT_FAILURE;
109                 }
110         
111                 // We need to be root to mount a filesystem, so, let us be elevated!
112                 setuid(0);      // I hope I have the setuid bit implemented.
113         }
114         else
115         {
116                 // Check that we were passed a filesystem type
117                 if(sType == NULL) {
118                         fprintf(stderr, "Please pass a filesystem type\n");
119                         return EXIT_FAILURE;
120                 }
121         }
122         
123         // Check Device
124         fd = open(sDevice, OPENFLAG_READ);
125         if(fd == -1) {
126                 printf("Device '%s' cannot be opened for reading\n", sDevice);
127                 return EXIT_FAILURE;
128         }
129         close(fd);
130         
131         // Check Mount Point
132         fd = open(sDir, OPENFLAG_EXEC);
133         if(fd == -1) {
134                 printf("Directory '%s' does not exist\n", sDir);
135                 return EXIT_FAILURE;
136         }
137         close(fd);
138
139         // Replace sOptions with an empty string if it is still NULL
140         if(sOptions == NULL)    sOptions = "";
141
142         // Let's Mount!
143         _SysMount(sDevice, sDir, sType, sOptions);
144
145         return 0;
146 }
147
148 void ShowUsage(char *ProgName)
149 {
150         fprintf(stderr, "Usage:\n");
151         fprintf(stderr, "    %s [-t <type>] <device> <directory> [-o <options>]\n", ProgName);
152         fprintf(stderr, "or  %s <device>\n", ProgName);
153         fprintf(stderr, "or  %s <directory>\n", ProgName);
154         fprintf(stderr, "or  %s\n", ProgName);
155 }
156
157 /**
158  * \fn int GetMountDefs(char *Ident, char **spDevice, char **spDir, char **spType, char **spOptions)
159  * \brief Reads the mountable definitions file and returns the corresponding entry
160  * \param spDevice      Pointer to a string (pointer) determining the device (also is the input for this function)
161  * \note STUB
162  */
163 int GetMountDefs(char *Ident, char **spDevice, char **spDir, char **spType, char **spOptions)
164 {
165         // TODO: Read the mounts file (after deciding what it will be)
166         return 0;
167 }

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