Remove unnecessary 0 checks before delete; see http://www.parashift.com/c++-faq-lite...
[ardour.git] / libs / pbd / mountpoint.cc
1 /*
2     Copyright (C) 2002 Paul Davis 
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18     $Id$
19 */
20
21 #include <cstdio>
22 #include <cstring>
23 #include <string>
24 #include <cstring>
25 #include <limits.h>
26
27 #include <pbd/mountpoint.h>
28
29 using std::string;
30
31 #if HAVE_GETMNTENT
32 #include <mntent.h>
33
34 struct mntent_sorter {
35     bool operator() (const mntent *a, const mntent *b) {
36             return strcmp (a->mnt_dir, b->mnt_dir);
37     }
38 };
39
40 string
41 mountpoint (string path)
42 {
43         FILE *mntf;
44         mntent *mnt;
45         unsigned int maxmatch = 0;
46         unsigned int matchlen;
47         const char *cpath = path.c_str();
48         char best[PATH_MAX+1];
49         
50         if ((mntf = setmntent ("/etc/mtab", "r")) == 0) {
51                 return "";
52         }
53
54         best[0] = '\0';
55
56         while ((mnt = getmntent (mntf))) {
57                 unsigned int n;
58
59                 n = 0;
60                 matchlen = 0;
61
62                 /* note: strcmp's semantics are not 
63                    strict enough to use for this.
64                 */
65
66                 while (cpath[n] && mnt->mnt_dir[n]) {
67                         if (cpath[n] != mnt->mnt_dir[n]) {
68                                 break;
69                         }
70                         matchlen++;
71                         n++;
72                 }
73
74                 if (cpath[matchlen] == '\0') {
75
76                         endmntent (mntf);
77                         return mnt->mnt_dir;
78
79                 } else {
80
81                         if (matchlen > maxmatch) {
82                                 snprintf (best, sizeof(best), "%s", mnt->mnt_dir);
83                                 maxmatch = matchlen;
84                         }
85                 }
86         }
87
88         endmntent (mntf);
89
90         return best;
91 }
92
93 #else // !HAVE_GETMNTENT
94
95 #include <sys/param.h>
96 #include <sys/ucred.h>
97 #include <sys/mount.h>
98
99 string
100 mountpoint (string path)
101 {
102         struct statfs *mntbufp = 0;
103         int count;
104         unsigned int maxmatch = 0;
105         unsigned int matchlen;
106         const char *cpath = path.c_str();
107         char best[PATH_MAX+1];
108         
109         if ((count = getmntinfo(&mntbufp, MNT_NOWAIT)) == 0) {
110                 free(mntbufp);
111                 return "\0";
112         }
113
114         best[0] = '\0';
115
116         for (int i = 0; i < count; ++i) {
117                 unsigned int n = 0;
118                 matchlen = 0;
119
120                 /* note: strcmp's semantics are not 
121                    strict enough to use for this.
122                 */
123
124                 while (cpath[n] && mntbufp[i].f_mntonname[n]) {
125                         if (cpath[n] != mntbufp[i].f_mntonname[n]) {
126                                 break;
127                         }
128                         matchlen++;
129                         n++;
130                 }
131
132                 if (cpath[matchlen] == '\0') {
133                         snprintf(best, sizeof(best), "%s", mntbufp[i].f_mntonname);
134                         free(mntbufp);
135                         return best;
136
137                 } else {
138
139                         if (matchlen > maxmatch) {
140                                 snprintf (best, sizeof(best), "%s", mntbufp[i].f_mntonname);
141                                 maxmatch = matchlen;
142                         }
143                 }
144         }
145
146         free(mntbufp);
147         
148         return best;
149 }
150 #endif // HAVE_GETMNTENT
151
152 #ifdef TEST_MOUNTPOINT
153                 
154 main (int argc, char *argv[])
155 {
156         printf ("mp of %s = %s\n", argv[1], mountpoint (argv[1]).c_str());
157         exit (0);
158 }
159
160 #endif // TEST_MOUNTPOINT