Forgot this file...
[oweals/busybox.git] / mtab.c
1 #include "internal.h"
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <errno.h>
5 #include <string.h>
6 #include <stdio.h>
7 #include <mntent.h>
8 #include <sys/mount.h>
9
10 extern const char mtab_file[]; /* Defined in utility.c */
11
12 static char *
13 stralloc(const char * string)
14 {
15         int     length = strlen(string) + 1;
16         char *  n = malloc(length);
17         memcpy(n, string, length);
18         return n;
19 }
20
21 extern void
22 erase_mtab(const char * name)
23 {
24         struct mntent   entries[20];
25         int     count = 0;
26         FILE *mountTable = setmntent(mtab_file, "r");
27         struct mntent * m;
28
29         if ( mountTable == 0
30          && (mountTable = setmntent("/proc/mounts", "r")) == 0 ) {
31                 perror(mtab_file);
32                 return;
33         }
34
35         while ( (m = getmntent(mountTable)) != 0 ) {
36                 entries[count].mnt_fsname = stralloc(m->mnt_fsname);
37                 entries[count].mnt_dir = stralloc(m->mnt_dir);
38                 entries[count].mnt_type = stralloc(m->mnt_type);
39                 entries[count].mnt_opts = stralloc(m->mnt_opts);
40                 entries[count].mnt_freq = m->mnt_freq;
41                 entries[count].mnt_passno = m->mnt_passno;
42                 count++;
43         }
44         endmntent(mountTable);
45         if ( (mountTable = setmntent(mtab_file, "w")) ) {
46                 int     i;
47                 for ( i = 0; i < count; i++ ) {
48                         int result = ( strcmp(entries[i].mnt_fsname, name) == 0
49                          || strcmp(entries[i].mnt_dir, name) == 0 );
50
51                         if ( result )
52                                 continue;
53                         else
54                                 addmntent(mountTable, &entries[i]);
55                 }
56                 endmntent(mountTable);
57         }
58         else if ( errno != EROFS )
59                 perror(mtab_file);
60 }
61
62 /*
63  * Given a block device, find the mount table entry if that block device
64  * is mounted.
65  *
66  * Given any other file (or directory), find the mount table entry for its
67  * filesystem.
68  */
69 static struct mntent *
70 findMountPoint(const char * name, const char * table)
71 {
72     struct stat s;
73     dev_t mountDevice;
74     FILE* mountTable;
75     struct mntent* mountEntry;
76
77     if ( stat(name, &s) != 0 )
78         return 0;
79
80     if ( (s.st_mode & S_IFMT) == S_IFBLK )
81         mountDevice = s.st_rdev;
82     else
83         mountDevice = s.st_dev;
84
85     
86     if ( (mountTable = setmntent(table, "r")) == 0 )
87         return 0;
88
89     while ( (mountEntry = getmntent(mountTable)) != 0 ) {
90         if ( strcmp(name, mountEntry->mnt_dir) == 0 || 
91                 strcmp(name, mountEntry->mnt_fsname) == 0 )     /* String match. */
92             break;
93         if ( stat(mountEntry->mnt_fsname, &s) == 0 && 
94                 s.st_rdev == mountDevice )      /* Match the device. */
95             break;
96         if ( stat(mountEntry->mnt_dir, &s) == 0 && 
97                 s.st_dev == mountDevice )       /* Match the directory's mount point. */
98             break;
99     }
100     endmntent(mountTable);
101     return mountEntry;
102 }
103
104 extern void 
105 write_mtab(char* blockDevice, char* directory, 
106         char* filesystemType, long flags, char* string_flags)
107 {
108         FILE *mountTable = setmntent(mtab_file, "a+");
109         struct mntent m;
110
111         if ( mountTable == 0 ) {
112                 perror(mtab_file);
113                 return;
114         }
115         if (mountTable) {
116             int length = strlen(directory);
117
118             if ( length > 1 && directory[length - 1] == '/' )
119                     directory[length - 1] = '\0';
120
121             if ( filesystemType == 0 ) {
122                     struct mntent *     p
123                      = findMountPoint(blockDevice, "/proc/mounts");
124
125                     if ( p && p->mnt_type )
126                             filesystemType = p->mnt_type;
127             }
128             m.mnt_fsname = blockDevice;
129             m.mnt_dir = directory;
130             m.mnt_type = filesystemType ? filesystemType : "default";
131             
132             if (*string_flags) {
133                     m.mnt_opts = string_flags;
134             } else {
135                     if ( (flags | MS_RDONLY) == flags )
136                             m.mnt_opts = "ro";
137                     else        
138                             m.mnt_opts = "rw";
139             }
140             
141             m.mnt_freq = 0;
142             m.mnt_passno = 0;
143             addmntent(mountTable, &m);
144             endmntent(mountTable);
145     }
146 }
147
148