(getuidbyname): Declare parameter to be const.
[coreutils.git] / lib / mountlist.c
blobde3e078c164e9654b24d8548b5ad487f42f928da
1 /* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992, 1997 Free Software Foundation, Inc.
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, or (at your option)
7 any later version.
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.
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 Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <sys/types.h>
24 #include "mountlist.h"
26 #ifdef STDC_HEADERS
27 # include <stdlib.h>
28 #else
29 void free ();
30 #endif
31 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
32 # include <string.h>
33 #else
34 # include <strings.h>
35 #endif
37 char *strstr ();
38 char *xmalloc ();
39 char *xrealloc ();
40 char *xstrdup ();
41 void error ();
43 #ifdef HAVE_SYS_PARAM_H
44 # include <sys/param.h>
45 #endif
47 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
48 # include <sys/mount.h>
49 # include <sys/fs_types.h>
50 #endif /* MOUNTED_GETFSSTAT */
52 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
53 # include <mntent.h>
54 # if !defined(MOUNTED)
55 # if defined(MNT_MNTTAB) /* HP-UX. */
56 # define MOUNTED MNT_MNTTAB
57 # endif
58 # if defined(MNTTABNAME) /* Dynix. */
59 # define MOUNTED MNTTABNAME
60 # endif
61 # endif
62 #endif
64 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
65 # include <sys/mount.h>
66 #endif
68 #ifdef MOUNTED_GETMNT /* Ultrix. */
69 # include <sys/mount.h>
70 # include <sys/fs_types.h>
71 #endif
73 #ifdef MOUNTED_FREAD /* SVR2. */
74 # include <mnttab.h>
75 #endif
77 #ifdef MOUNTED_FREAD_FSTYP /* SVR3. */
78 # include <mnttab.h>
79 # include <sys/fstyp.h>
80 # include <sys/statfs.h>
81 #endif
83 #ifdef MOUNTED_LISTMNTENT
84 # include <mntent.h>
85 #endif
87 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
88 # include <sys/mnttab.h>
89 #endif
91 #ifdef MOUNTED_VMOUNT /* AIX. */
92 # include <fshelp.h>
93 # include <sys/vfs.h>
94 #endif
96 #ifdef DOLPHIN
97 /* So special that it's not worth putting this in autoconf. */
98 # undef MOUNTED_FREAD_FSTYP
99 # define MOUNTED_GETMNTTBL
100 #endif
102 #ifdef HAVE_SYS_MNTENT_H
103 /* This is to get MNTOPT_IGNORE on e.g. SVR4. */
104 # include <sys/mntent.h>
105 #endif
107 #if defined (MNTOPT_IGNORE) && defined (HAVE_HASMNTOPT)
108 # define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
109 #else
110 # define MNT_IGNORE(M) 0
111 #endif
113 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
114 /* Return the value of the hexadecimal number represented by CP.
115 No prefix (like '0x') or suffix (like 'h') is expected to be
116 part of CP. */
118 static int
119 xatoi (cp)
120 char *cp;
122 int val;
124 val = 0;
125 while (*cp)
127 if (*cp >= 'a' && *cp <= 'f')
128 val = val * 16 + *cp - 'a' + 10;
129 else if (*cp >= 'A' && *cp <= 'F')
130 val = val * 16 + *cp - 'A' + 10;
131 else if (*cp >= '0' && *cp <= '9')
132 val = val * 16 + *cp - '0';
133 else
134 break;
135 cp++;
137 return val;
139 #endif /* MOUNTED_GETMNTENT1. */
141 #if defined (MOUNTED_GETMNTINFO) && !defined (__NetBSD__) && !defined (__OpenBSD__)
142 static char *
143 fstype_to_string (t)
144 short t;
146 switch (t)
148 # ifdef MOUNT_PC
149 case MOUNT_PC:
150 return "pc";
151 # endif
152 # ifdef MOUNT_MFS
153 case MOUNT_MFS:
154 return "mfs";
155 # endif
156 # ifdef MOUNT_LO
157 case MOUNT_LO:
158 return "lo";
159 # endif
160 # ifdef MOUNT_TFS
161 case MOUNT_TFS:
162 return "tfs";
163 # endif
164 # ifdef MOUNT_TMP
165 case MOUNT_TMP:
166 return "tmp";
167 # endif
168 # ifdef MOUNT_UFS
169 case MOUNT_UFS:
170 return "ufs" ;
171 # endif
172 # ifdef MOUNT_NFS
173 case MOUNT_NFS:
174 return "nfs" ;
175 # endif
176 # ifdef MOUNT_MSDOS
177 case MOUNT_MSDOS:
178 return "msdos" ;
179 # endif
180 # ifdef MOUNT_LFS
181 case MOUNT_LFS:
182 return "lfs" ;
183 # endif
184 # ifdef MOUNT_LOFS
185 case MOUNT_LOFS:
186 return "lofs" ;
187 # endif
188 # ifdef MOUNT_FDESC
189 case MOUNT_FDESC:
190 return "fdesc" ;
191 # endif
192 # ifdef MOUNT_PORTAL
193 case MOUNT_PORTAL:
194 return "portal" ;
195 # endif
196 # ifdef MOUNT_NULL
197 case MOUNT_NULL:
198 return "null" ;
199 # endif
200 # ifdef MOUNT_UMAP
201 case MOUNT_UMAP:
202 return "umap" ;
203 # endif
204 # ifdef MOUNT_KERNFS
205 case MOUNT_KERNFS:
206 return "kernfs" ;
207 # endif
208 # ifdef MOUNT_PROCFS
209 case MOUNT_PROCFS:
210 return "procfs" ;
211 # endif
212 # ifdef MOUNT_AFS
213 case MOUNT_AFS:
214 return "afs" ;
215 # endif
216 # ifdef MOUNT_CD9660
217 case MOUNT_CD9660:
218 return "cd9660" ;
219 # endif
220 # ifdef MOUNT_UNION
221 case MOUNT_UNION:
222 return "union" ;
223 # endif
224 # ifdef MOUNT_DEVFS
225 case MOUNT_DEVFS:
226 return "devfs" ;
227 # endif
228 # ifdef MOUNT_EXT2FS
229 case MOUNT_EXT2FS:
230 return "ext2fs" ;
231 # endif
232 default:
233 return "?";
236 #endif /* MOUNTED_GETMNTINFO */
238 #ifdef MOUNTED_VMOUNT /* AIX. */
239 static char *
240 fstype_to_string (t)
241 int t;
243 struct vfs_ent *e;
245 e = getvfsbytype (t);
246 if (!e || !e->vfsent_name)
247 return "none";
248 else
249 return e->vfsent_name;
251 #endif /* MOUNTED_VMOUNT */
253 /* Return a list of the currently mounted filesystems, or NULL on error.
254 Add each entry to the tail of the list so that they stay in order.
255 If NEED_FS_TYPE is nonzero, ensure that the filesystem type fields in
256 the returned list are valid. Otherwise, they might not be.
257 If ALL_FS is zero, do not return entries for filesystems that
258 are automounter (dummy) entries. */
260 struct mount_entry *
261 read_filesystem_list (need_fs_type, all_fs)
262 int need_fs_type, all_fs;
264 struct mount_entry *mount_list;
265 struct mount_entry *me;
266 struct mount_entry *mtail;
268 /* Start the list off with a dummy entry. */
269 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
270 me->me_next = NULL;
271 mount_list = mtail = me;
273 #ifdef MOUNTED_LISTMNTENT
275 struct tabmntent *mntlist, *p;
276 struct mntent *mnt;
277 struct mount_entry *me;
279 /* the third and fourth arguments could be used to filter mounts,
280 but Crays doesn't seem to have any mounts that we want to
281 remove. Specifically, automount create normal NFS mounts.
284 if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0)
285 return NULL;
286 p = mntlist;
287 while(p){
288 mnt = p->ment;
289 me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry));
290 me->me_devname = xstrdup(mnt->mnt_fsname);
291 me->me_mountdir = xstrdup(mnt->mnt_dir);
292 me->me_type = xstrdup(mnt->mnt_type);
293 me->me_dev = -1;
294 me->me_next = NULL;
295 mtail->me_next = me;
296 mtail = me;
297 p = p->next;
299 freemntlist(mntlist);
301 #endif
303 #ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
305 struct mntent *mnt;
306 char *table = MOUNTED;
307 FILE *fp;
308 char *devopt;
310 fp = setmntent (table, "r");
311 if (fp == NULL)
312 return NULL;
314 while ((mnt = getmntent (fp)))
316 if (!all_fs && (!strcmp (mnt->mnt_type, "ignore")
317 || !strcmp (mnt->mnt_type, "auto")))
318 continue;
320 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
321 me->me_devname = xstrdup (mnt->mnt_fsname);
322 me->me_mountdir = xstrdup (mnt->mnt_dir);
323 me->me_type = xstrdup (mnt->mnt_type);
324 devopt = strstr (mnt->mnt_opts, "dev=");
325 if (devopt)
327 if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
328 me->me_dev = xatoi (devopt + 6);
329 else
330 me->me_dev = xatoi (devopt + 4);
332 else
333 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
334 me->me_next = NULL;
336 /* Add to the linked list. */
337 mtail->me_next = me;
338 mtail = me;
341 if (endmntent (fp) == 0)
342 return NULL;
344 #endif /* MOUNTED_GETMNTENT1. */
346 #ifdef MOUNTED_GETMNTINFO /* 4.4BSD. */
348 struct statfs *fsp;
349 int entries;
351 entries = getmntinfo (&fsp, MNT_NOWAIT);
352 if (entries < 0)
353 return NULL;
354 while (entries-- > 0)
356 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
357 me->me_devname = xstrdup (fsp->f_mntfromname);
358 me->me_mountdir = xstrdup (fsp->f_mntonname);
359 # if defined (__NetBSD__) || defined (__OpenBSD__)
360 me->me_type = xstrdup (fsp->f_fstypename);
361 # else
362 me->me_type = fstype_to_string (fsp->f_type);
363 # endif
364 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
365 me->me_next = NULL;
367 /* Add to the linked list. */
368 mtail->me_next = me;
369 mtail = me;
370 fsp++;
373 #endif /* MOUNTED_GETMNTINFO */
375 #ifdef MOUNTED_GETMNT /* Ultrix. */
377 int offset = 0;
378 int val;
379 struct fs_data fsd;
381 while ((val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
382 (char *) 0)) > 0)
384 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
385 me->me_devname = xstrdup (fsd.fd_req.devname);
386 me->me_mountdir = xstrdup (fsd.fd_req.path);
387 me->me_type = gt_names[fsd.fd_req.fstype];
388 me->me_dev = fsd.fd_req.dev;
389 me->me_next = NULL;
391 /* Add to the linked list. */
392 mtail->me_next = me;
393 mtail = me;
395 if (val < 0)
396 return NULL;
398 #endif /* MOUNTED_GETMNT. */
400 #if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */
402 int numsys, counter, bufsize;
403 struct statfs *stats;
405 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
406 if (numsys < 0)
407 return (NULL);
409 bufsize = (1 + numsys) * sizeof (struct statfs);
410 stats = (struct statfs *)xmalloc (bufsize);
411 numsys = getfsstat (stats, bufsize, MNT_WAIT);
413 if (numsys < 0)
415 free (stats);
416 return (NULL);
419 for (counter = 0; counter < numsys; counter++)
421 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
422 me->me_devname = xstrdup (stats[counter].f_mntfromname);
423 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
424 me->me_type = mnt_names[stats[counter].f_type];
425 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
426 me->me_next = NULL;
428 /* Add to the linked list. */
429 mtail->me_next = me;
430 mtail = me;
433 free (stats);
435 #endif /* MOUNTED_GETFSSTAT */
437 #if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */
439 struct mnttab mnt;
440 char *table = "/etc/mnttab";
441 FILE *fp;
443 fp = fopen (table, "r");
444 if (fp == NULL)
445 return NULL;
447 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
449 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
450 # ifdef GETFSTYP /* SVR3. */
451 me->me_devname = xstrdup (mnt.mt_dev);
452 # else
453 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
454 strcpy (me->me_devname, "/dev/");
455 strcpy (me->me_devname + 5, mnt.mt_dev);
456 # endif
457 me->me_mountdir = xstrdup (mnt.mt_filsys);
458 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
459 me->me_type = "";
460 # ifdef GETFSTYP /* SVR3. */
461 if (need_fs_type)
463 struct statfs fsd;
464 char typebuf[FSTYPSZ];
466 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
467 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
468 me->me_type = xstrdup (typebuf);
470 # endif
471 me->me_next = NULL;
473 /* Add to the linked list. */
474 mtail->me_next = me;
475 mtail = me;
478 if (fclose (fp) == EOF)
479 return NULL;
481 #endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP. */
483 #ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
485 struct mntent **mnttbl=getmnttbl(),**ent;
486 for (ent=mnttbl;*ent;ent++)
488 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
489 me->me_devname = xstrdup ( (*ent)->mt_resource);
490 me->me_mountdir = xstrdup( (*ent)->mt_directory);
491 me->me_type = xstrdup ((*ent)->mt_fstype);
492 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
493 me->me_next = NULL;
495 /* Add to the linked list. */
496 mtail->me_next = me;
497 mtail = me;
499 endmnttbl();
501 #endif
503 #ifdef MOUNTED_GETMNTENT2 /* SVR4. */
505 struct mnttab mnt;
506 char *table = MNTTAB;
507 FILE *fp;
508 int ret;
510 fp = fopen (table, "r");
511 if (fp == NULL)
512 return NULL;
514 while ((ret = getmntent (fp, &mnt)) == 0)
516 /* Don't show automounted filesystems twice on e.g., Solaris. */
517 if (!all_fs && MNT_IGNORE (&mnt))
518 continue;
520 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
521 me->me_devname = xstrdup (mnt.mnt_special);
522 me->me_mountdir = xstrdup (mnt.mnt_mountp);
523 me->me_type = xstrdup (mnt.mnt_fstype);
524 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
525 me->me_next = NULL;
527 /* Add to the linked list. */
528 mtail->me_next = me;
529 mtail = me;
532 if (ret > 0)
533 return NULL;
534 if (fclose (fp) == EOF)
535 return NULL;
537 #endif /* MOUNTED_GETMNTENT2. */
539 #ifdef MOUNTED_VMOUNT /* AIX. */
541 int bufsize;
542 char *entries, *thisent;
543 struct vmount *vmp;
545 /* Ask how many bytes to allocate for the mounted filesystem info. */
546 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
547 entries = xmalloc (bufsize);
549 /* Get the list of mounted filesystems. */
550 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
552 for (thisent = entries; thisent < entries + bufsize;
553 thisent += vmp->vmt_length)
555 vmp = (struct vmount *) thisent;
556 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
557 if (vmp->vmt_flags & MNT_REMOTE)
559 char *host, *path;
561 /* Prepend the remote pathname. */
562 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
563 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
564 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
565 strcpy (me->me_devname, host);
566 strcat (me->me_devname, ":");
567 strcat (me->me_devname, path);
569 else
571 me->me_devname = xstrdup (thisent +
572 vmp->vmt_data[VMT_OBJECT].vmt_off);
574 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
575 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
576 me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want. */
577 me->me_next = NULL;
579 /* Add to the linked list. */
580 mtail->me_next = me;
581 mtail = me;
583 free (entries);
585 #endif /* MOUNTED_VMOUNT. */
587 /* Free the dummy head. */
588 me = mount_list;
589 mount_list = mount_list->me_next;
590 free (me);
591 return mount_list;