Aggiornamento note copyright
[gapil.git] / sources / mymount.c
1 /* mymount.c
2  * 
3  * Copyright (C) 2012 Simone Piccardi
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /*****************************************************************************
20  *
21  * File mymount.c: An example for mount function
22  *
23  * Author: S. Piccardi Jan. 2012
24  *
25  *****************************************************************************/
26 #include <sys/types.h>   /* primitive system data types */
27 #include <sys/stat.h>    /* file characteristics constants and functions */
28 #include <stdlib.h>      /* C standard library */
29 #include <stdio.h>       /* standard I/O library */
30 #include <unistd.h>      /* unix standard library */
31 #include <string.h>
32 #include <sys/mount.h>
33
34 /* pass -D DEBUG to gcc to enable debug printing */
35 #ifdef DEBUG
36 #define debug printf
37 #else
38 #define debug(fmt, arg...)
39 #endif /* DEBUG */
40
41 /* Adding undefined flags in glibc headers */ 
42 #ifndef MS_DIRSYNC      
43 #define MS_DIRSYNC 128
44 #endif
45 #ifndef MS_BIND         
46 #define MS_BIND 4096
47 #endif
48 #ifndef MS_MOVE         
49 #define MS_MOVE 8192
50 #endif
51 #ifndef MS_REC          
52 #define MS_REC 16384
53 #endif
54 #ifndef MS_SILENT         
55 #define MS_SILENT 32768
56 #endif
57 #ifndef MS_UNBINDABLE   
58 #define MS_UNBINDABLE (1<<17) 
59 #endif
60 #ifndef MS_PRIVATE     
61 #define MS_PRIVATE (1<<18)
62 #endif
63 #ifndef MS_SLAVE         
64 #define MS_SLAVE (1<<19) 
65 #endif
66 #ifndef MS_SHARED       
67 #define MS_SHARED (1<<20)
68 #endif
69 #ifndef MS_RELATIME       
70 #define MS_RELATIME (1<<21)
71 #endif
72 #ifndef MS_STRICTATIME       
73 #define MS_STRICTATIME (1<<24)
74 #endif
75
76
77 /*
78  * Program mymount
79  */
80 /* Help printing routine */
81 void usage(void);
82
83 /* struct for name<->flag correspondence */
84 struct ms_flag {
85     const char *name;
86     int flag;
87 };
88
89 /* compare funtion to find a flag name */
90 int ms_flag_cmp(const void *c1, const void *c2) 
91 {
92     struct ms_flag *v1 = (struct ms_flag *) c1;
93     struct ms_flag *v2 = (struct ms_flag *) c2;
94     return strcmp(v1->name, v2->name);
95 }
96
97 /* main body */
98 int main(int argc, char *argv[]) 
99 {
100 /* 
101  * Variables definition
102  */
103     int i, flags=0;
104     char * mountflags=NULL, *data=NULL, *filesystemtype=NULL;
105     char *token;
106     /* mount flag table, must be alphabetically ordered */
107     struct ms_flag ms_values[]=
108         {
109             {"bind", MS_BIND},
110             {"dirsync",MS_DIRSYNC},
111             {"mandlock",MS_MANDLOCK},
112             {"move",MS_MOVE},
113             {"noatime",MS_NOATIME},
114             {"nodev",MS_NODEV},
115             {"nodiratime",MS_NODIRATIME},
116             {"noexec",MS_NOEXEC},
117             {"nosuid",MS_NOSUID},
118             {"private",MS_PRIVATE},
119             {"rdonly",MS_RDONLY},
120             {"rec",MS_REC},
121             {"relatime",MS_RELATIME},
122             {"remount",MS_REMOUNT},
123             {"share",MS_SHARED},
124             {"silent",MS_SILENT},
125             {"slave",MS_SLAVE},
126             {"strictatime",MS_STRICTATIME},
127             {"synchronous",MS_SYNCHRONOUS},
128             {"unbindable",MS_UNBINDABLE}
129         };
130     struct ms_flag key, *result;
131     int ms_count = sizeof(ms_values)/sizeof(struct ms_flag);
132
133     /*
134      * Input section: decode command line parameters 
135      * Use getopt function
136      */
137     opterr = 0;  /* don't want writing to stderr */
138     while ( (i = getopt(argc, argv, "o:f:t:h")) != -1) {
139         switch (i) {
140         /* 
141          * Handling options 
142          */ 
143         case 'h':                                  /* help option */
144             printf("Wrong -h option use\n");
145             usage();
146             return -1;
147             break;
148         case 'o':                                  /* options data */
149             data = optarg;
150             debug("passed option data: %s\n", data);
151             break;
152         case 't':                                  /* filesystem type */
153             filesystemtype = optarg;
154             debug("passed filesystem type: %s\n", filesystemtype);
155             break;
156         case 'f':                                  /* mount flags */ 
157             mountflags = optarg;
158             debug("passed mount flags: %s\n", mountflags);
159             break;
160         case '?':                                  /* unrecognized options */
161             printf("Unrecognized options -%c\n",optopt);
162             usage();
163         default:                                   /* should not reached */
164             usage();
165         }
166     }
167     /* ***********************************************************
168      * 
169      *           Options processing completed
170      *
171      *                Main code beginning
172      * 
173      * ***********************************************************/
174     /* There must be 2 arguments, source and target */
175     if ((argc - optind) != 2) {   
176         printf("Wrong number of arguments %d\n", argc - optind);
177         usage();
178     }
179     debug("source %s, target %s\n",argv[optind], argv[optind+1]);
180
181     /* parse -f option parameter, and build mount flags argument */ 
182     if ( token = strtok(mountflags, ",") ) {
183         do {
184             key.name = token;
185             result = bsearch(&key, ms_values, ms_count, sizeof(struct ms_flag),
186                              ms_flag_cmp);
187             if (result) {
188                 debug("found option: %s\n",result->name);
189                 flags |= result->flag;
190             } else {
191                 printf("unknown flag: %s\n", key.name);
192                 exit(EXIT_FAILURE);
193             }
194         } while (token=strtok(NULL,","));
195     }
196     debug("flags value %X\n", flags);
197     /* do mount */
198     if (mount(argv[optind], argv[optind + 1], filesystemtype, flags, data) == -1) {
199         perror("Mount call failed");
200         exit(EXIT_FAILURE);
201     }
202     exit(EXIT_SUCCESS);
203 }
204 /*
205  * routine to print usage info and exit
206  */
207 void usage(void) {
208     printf("Program mymount:  \n");
209     printf("Usage:\n");
210     printf("mymount [-h] [-o opt1[,...]] [-t type] [-f fl1[,...]] source target\n");
211     printf("  -h          print this help\n");
212     printf("  -o options  comma separated options data string\n");
213     printf("  -t fstype   filesystemtype string\n");
214     printf("  -f flags    comma separated mount flags string\n");
215     printf("\n");
216     printf("you always need to specify two argument, source and target,\n");
217     printf("matching the system call ones, if one of them is not needed\n");
218     printf("just pass an empty string\n");
219     printf("you also need to specify options and flag, give an empty \n");
220     printf("string for option if you don't want to set any, i.e. \n");
221     printf("   ./mymount -t ext4 -o "" -f remount,rdonly /dev/sdb1 /mnt");
222     exit(1);
223 }