summaryrefslogtreecommitdiffstats
path: root/lib/mountlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mountlist.c')
-rw-r--r--lib/mountlist.c213
1 files changed, 128 insertions, 85 deletions
diff --git a/lib/mountlist.c b/lib/mountlist.c
index 1af3cbb..631be31 100644
--- a/lib/mountlist.c
+++ b/lib/mountlist.c
@@ -1,5 +1,5 @@
1/* mountlist.c -- return a list of mounted filesystems 1/* mountlist.c -- return a list of mounted filesystems
2 Copyright (C) 1991, 1992, 1997-2000 Free Software Foundation, Inc. 2 Copyright (C) 1991, 1992, 1997-2004 Free Software Foundation, Inc.
3 3
4 This program is free software; you can redistribute it and/or modify 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 5 it under the terms of the GNU General Public License as published by
@@ -15,29 +15,24 @@
15 along with this program; if not, write to the Free Software Foundation, 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. */ 16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17 17
18#include "config.h" 18#if HAVE_CONFIG_H
19# include <config.h>
20#endif
19 21
20#include <stdio.h> 22#include <stdio.h>
21#include <sys/types.h> 23#include <sys/types.h>
22#include "mountlist.h" 24#include <stdlib.h>
25#include <string.h>
23 26
24#ifdef STDC_HEADERS 27#include "xalloc.h"
25# include <stdlib.h> 28
26#else 29#ifndef SIZE_MAX
27void free (); 30# define SIZE_MAX ((size_t) -1)
28#endif
29#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
30# include <string.h>
31#else
32# include <strings.h>
33#endif 31#endif
34 32
35#ifndef strstr 33#ifndef strstr
36char *strstr (); 34char *strstr ();
37#endif 35#endif
38/* char *xmalloc (); */
39/* char *realloc (); */
40/* char *xstrdup (); */
41 36
42#include <errno.h> 37#include <errno.h>
43#ifndef errno 38#ifndef errno
@@ -56,18 +51,35 @@ extern int errno;
56# include <sys/param.h> 51# include <sys/param.h>
57#endif 52#endif
58 53
59#if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */ 54#if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */
60# include <sys/mount.h> 55# if HAVE_SYS_UCRED_H
61# include <sys/fs_types.h> 56# include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS,
57 NGROUPS is used as an array dimension in ucred.h */
58# include <sys/ucred.h> /* needed by powerpc-apple-darwin1.3.7 */
59# endif
60# if HAVE_SYS_MOUNT_H
61# include <sys/mount.h>
62# endif
63# if HAVE_SYS_FS_TYPES_H
64# include <sys/fs_types.h> /* needed by powerpc-apple-darwin1.3.7 */
65# endif
66# if HAVE_STRUCT_FSSTAT_F_FSTYPENAME
67# define FS_TYPE(Ent) ((Ent).f_fstypename)
68# else
69# define FS_TYPE(Ent) mnt_names[(Ent).f_type]
70# endif
62#endif /* MOUNTED_GETFSSTAT */ 71#endif /* MOUNTED_GETFSSTAT */
63 72
64#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ 73#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
65# include <mntent.h> 74# include <mntent.h>
66# if !defined(MOUNTED) 75# if !defined MOUNTED
67# if defined(MNT_MNTTAB) /* HP-UX. */ 76# if defined _PATH_MOUNTED /* GNU libc */
77# define MOUNTED _PATH_MOUNTED
78# endif
79# if defined MNT_MNTTAB /* HP-UX. */
68# define MOUNTED MNT_MNTTAB 80# define MOUNTED MNT_MNTTAB
69# endif 81# endif
70# if defined(MNTTABNAME) /* Dynix. */ 82# if defined MNTTABNAME /* Dynix. */
71# define MOUNTED MNTTABNAME 83# define MOUNTED MNTTABNAME
72# endif 84# endif
73# endif 85# endif
@@ -121,12 +133,16 @@ extern int errno;
121# include <sys/mntent.h> 133# include <sys/mntent.h>
122#endif 134#endif
123 135
124#if defined (MNTOPT_IGNORE) && defined (HAVE_HASMNTOPT) 136#undef MNT_IGNORE
137#if defined MNTOPT_IGNORE && defined HAVE_HASMNTOPT
125# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE) 138# define MNT_IGNORE(M) hasmntopt ((M), MNTOPT_IGNORE)
126#else 139#else
127# define MNT_IGNORE(M) 0 140# define MNT_IGNORE(M) 0
128#endif 141#endif
129 142
143#include "mountlist.h"
144#include "unlocked-io.h"
145
130#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */ 146#ifdef MOUNTED_GETMNTENT1 /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
131/* Return the value of the hexadecimal number represented by CP. 147/* Return the value of the hexadecimal number represented by CP.
132 No prefix (like '0x') or suffix (like 'h') is expected to be 148 No prefix (like '0x') or suffix (like 'h') is expected to be
@@ -303,21 +319,22 @@ read_filesystem_list (int need_fs_type)
303 remove. Specifically, automount create normal NFS mounts. 319 remove. Specifically, automount create normal NFS mounts.
304 */ 320 */
305 321
306 if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) 322 if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0)
307 return NULL; 323 return NULL;
308 for (p = mntlist; p; p = p->next) { 324 for (p = mntlist; p; p = p->next) {
309 mnt = p->ment; 325 mnt = p->ment;
310 me = (struct mount_entry*) malloc(sizeof (struct mount_entry)); 326 me = xmalloc (sizeof *me);
311 me->me_devname = strdup(mnt->mnt_fsname); 327 me->me_devname = xstrdup (mnt->mnt_fsname);
312 me->me_mountdir = strdup(mnt->mnt_dir); 328 me->me_mountdir = xstrdup (mnt->mnt_dir);
313 me->me_type = strdup(mnt->mnt_type); 329 me->me_type = xstrdup (mnt->mnt_type);
330 me->me_type_malloced = 1;
314 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 331 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
315 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 332 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
316 me->me_dev = -1; 333 me->me_dev = -1;
317 *mtail = me; 334 *mtail = me;
318 mtail = &me->me_next; 335 mtail = &me->me_next;
319 } 336 }
320 freemntlist(mntlist); 337 freemntlist (mntlist);
321 } 338 }
322#endif 339#endif
323 340
@@ -334,10 +351,11 @@ read_filesystem_list (int need_fs_type)
334 351
335 while ((mnt = getmntent (fp))) 352 while ((mnt = getmntent (fp)))
336 { 353 {
337 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 354 me = xmalloc (sizeof *me);
338 me->me_devname = strdup (mnt->mnt_fsname); 355 me->me_devname = xstrdup (mnt->mnt_fsname);
339 me->me_mountdir = strdup (mnt->mnt_dir); 356 me->me_mountdir = xstrdup (mnt->mnt_dir);
340 me->me_type = strdup (mnt->mnt_type); 357 me->me_type = xstrdup (mnt->mnt_type);
358 me->me_type_malloced = 1;
341 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 359 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
342 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 360 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
343 devopt = strstr (mnt->mnt_opts, "dev="); 361 devopt = strstr (mnt->mnt_opts, "dev=");
@@ -373,10 +391,11 @@ read_filesystem_list (int need_fs_type)
373 { 391 {
374 char *fs_type = fsp_to_string (fsp); 392 char *fs_type = fsp_to_string (fsp);
375 393
376 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 394 me = xmalloc (sizeof *me);
377 me->me_devname = strdup (fsp->f_mntfromname); 395 me->me_devname = xstrdup (fsp->f_mntfromname);
378 me->me_mountdir = strdup (fsp->f_mntonname); 396 me->me_mountdir = xstrdup (fsp->f_mntonname);
379 me->me_type = fs_type; 397 me->me_type = fs_type;
398 me->me_type_malloced = 0;
380 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 399 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
381 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 400 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
382 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ 401 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
@@ -398,10 +417,11 @@ read_filesystem_list (int need_fs_type)
398 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 417 0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
399 (char *) 0))) 418 (char *) 0)))
400 { 419 {
401 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 420 me = xmalloc (sizeof *me);
402 me->me_devname = strdup (fsd.fd_req.devname); 421 me->me_devname = xstrdup (fsd.fd_req.devname);
403 me->me_mountdir = strdup (fsd.fd_req.path); 422 me->me_mountdir = xstrdup (fsd.fd_req.path);
404 me->me_type = gt_names[fsd.fd_req.fstype]; 423 me->me_type = gt_names[fsd.fd_req.fstype];
424 me->me_type_malloced = 0;
405 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 425 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
406 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 426 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
407 me->me_dev = fsd.fd_req.dev; 427 me->me_dev = fsd.fd_req.dev;
@@ -415,7 +435,7 @@ read_filesystem_list (int need_fs_type)
415 } 435 }
416#endif /* MOUNTED_GETMNT. */ 436#endif /* MOUNTED_GETMNT. */
417 437
418#if defined (MOUNTED_FS_STAT_DEV) /* BeOS */ 438#if defined MOUNTED_FS_STAT_DEV /* BeOS */
419 { 439 {
420 /* The next_dev() and fs_stat_dev() system calls give the list of 440 /* The next_dev() and fs_stat_dev() system calls give the list of
421 all filesystems, including the information returned by statvfs() 441 all filesystems, including the information returned by statvfs()
@@ -458,19 +478,17 @@ read_filesystem_list (int need_fs_type)
458 continue; 478 continue;
459 479
460 if (strcmp (d->d_name, ".") == 0) 480 if (strcmp (d->d_name, ".") == 0)
461 name = strdup ("/"); 481 name = xstrdup ("/");
462 else 482 else
463 { 483 {
464 name = malloc (1 + strlen (d->d_name) + 1); 484 name = xmalloc (1 + strlen (d->d_name) + 1);
465 name[0] = '/'; 485 name[0] = '/';
466 strcpy (name + 1, d->d_name); 486 strcpy (name + 1, d->d_name);
467 } 487 }
468 488
469 if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode)) 489 if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
470 { 490 {
471 struct rootdir_entry *re; 491 struct rootdir_entry *re = xmalloc (sizeof *re);
472
473 re = (struct rootdir_entry *) malloc (sizeof (struct rootdir_entry));
474 re->name = name; 492 re->name = name;
475 re->dev = statbuf.st_dev; 493 re->dev = statbuf.st_dev;
476 re->ino = statbuf.st_ino; 494 re->ino = statbuf.st_ino;
@@ -496,10 +514,11 @@ read_filesystem_list (int need_fs_type)
496 if (re->dev == fi.dev && re->ino == fi.root) 514 if (re->dev == fi.dev && re->ino == fi.root)
497 break; 515 break;
498 516
499 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 517 me = xmalloc (sizeof *me);
500 me->me_devname = strdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name); 518 me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name);
501 me->me_mountdir = strdup (re != NULL ? re->name : fi.fsh_name); 519 me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name);
502 me->me_type = strdup (fi.fsh_name); 520 me->me_type = xstrdup (fi.fsh_name);
521 me->me_type_malloced = 1;
503 me->me_dev = fi.dev; 522 me->me_dev = fi.dev;
504 me->me_dummy = 0; 523 me->me_dummy = 0;
505 me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0; 524 me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0;
@@ -520,18 +539,21 @@ read_filesystem_list (int need_fs_type)
520 } 539 }
521#endif /* MOUNTED_FS_STAT_DEV */ 540#endif /* MOUNTED_FS_STAT_DEV */
522 541
523#if defined (MOUNTED_GETFSSTAT) /* __alpha running OSF_1 */ 542#if defined MOUNTED_GETFSSTAT /* __alpha running OSF_1 */
524 { 543 {
525 int numsys, counter, bufsize; 544 int numsys, counter;
545 size_t bufsize;
526 struct statfs *stats; 546 struct statfs *stats;
527 547
528 numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT); 548 numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT);
529 if (numsys < 0) 549 if (numsys < 0)
530 return (NULL); 550 return (NULL);
551 if (SIZE_MAX / sizeof *stats <= numsys)
552 xalloc_die ();
531 553
532 bufsize = (1 + numsys) * sizeof (struct statfs); 554 bufsize = (1 + numsys) * sizeof *stats;
533 stats = (struct statfs *)malloc (bufsize); 555 stats = xmalloc (bufsize);
534 numsys = getfsstat (stats, bufsize, MNT_WAIT); 556 numsys = getfsstat (stats, bufsize, MNT_NOWAIT);
535 557
536 if (numsys < 0) 558 if (numsys < 0)
537 { 559 {
@@ -541,10 +563,11 @@ read_filesystem_list (int need_fs_type)
541 563
542 for (counter = 0; counter < numsys; counter++) 564 for (counter = 0; counter < numsys; counter++)
543 { 565 {
544 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 566 me = xmalloc (sizeof *me);
545 me->me_devname = strdup (stats[counter].f_mntfromname); 567 me->me_devname = xstrdup (stats[counter].f_mntfromname);
546 me->me_mountdir = strdup (stats[counter].f_mntonname); 568 me->me_mountdir = xstrdup (stats[counter].f_mntonname);
547 me->me_type = mnt_names[stats[counter].f_type]; 569 me->me_type = xstrdup (FS_TYPE (stats[counter]));
570 me->me_type_malloced = 1;
548 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 571 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
549 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 572 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
550 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ 573 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
@@ -558,7 +581,7 @@ read_filesystem_list (int need_fs_type)
558 } 581 }
559#endif /* MOUNTED_GETFSSTAT */ 582#endif /* MOUNTED_GETFSSTAT */
560 583
561#if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23]. */ 584#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23]. */
562 { 585 {
563 struct mnttab mnt; 586 struct mnttab mnt;
564 char *table = "/etc/mnttab"; 587 char *table = "/etc/mnttab";
@@ -570,17 +593,18 @@ read_filesystem_list (int need_fs_type)
570 593
571 while (fread (&mnt, sizeof mnt, 1, fp) > 0) 594 while (fread (&mnt, sizeof mnt, 1, fp) > 0)
572 { 595 {
573 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 596 me = xmalloc (sizeof *me);
574# ifdef GETFSTYP /* SVR3. */ 597# ifdef GETFSTYP /* SVR3. */
575 me->me_devname = strdup (mnt.mt_dev); 598 me->me_devname = xstrdup (mnt.mt_dev);
576# else 599# else
577 me->me_devname = malloc (strlen (mnt.mt_dev) + 6); 600 me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
578 strcpy (me->me_devname, "/dev/"); 601 strcpy (me->me_devname, "/dev/");
579 strcpy (me->me_devname + 5, mnt.mt_dev); 602 strcpy (me->me_devname + 5, mnt.mt_dev);
580# endif 603# endif
581 me->me_mountdir = strdup (mnt.mt_filsys); 604 me->me_mountdir = xstrdup (mnt.mt_filsys);
582 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ 605 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
583 me->me_type = ""; 606 me->me_type = "";
607 me->me_type_malloced = 0;
584# ifdef GETFSTYP /* SVR3. */ 608# ifdef GETFSTYP /* SVR3. */
585 if (need_fs_type) 609 if (need_fs_type)
586 { 610 {
@@ -589,7 +613,10 @@ read_filesystem_list (int need_fs_type)
589 613
590 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1 614 if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
591 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1) 615 && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
592 me->me_type = strdup (typebuf); 616 {
617 me->me_type = xstrdup (typebuf);
618 me->me_type_malloced = 1;
619 }
593 } 620 }
594# endif 621# endif
595 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 622 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
@@ -602,6 +629,7 @@ read_filesystem_list (int need_fs_type)
602 629
603 if (ferror (fp)) 630 if (ferror (fp))
604 { 631 {
632 /* The last fread() call must have failed. */
605 int saved_errno = errno; 633 int saved_errno = errno;
606 fclose (fp); 634 fclose (fp);
607 errno = saved_errno; 635 errno = saved_errno;
@@ -615,13 +643,14 @@ read_filesystem_list (int need_fs_type)
615 643
616#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */ 644#ifdef MOUNTED_GETMNTTBL /* DolphinOS goes it's own way */
617 { 645 {
618 struct mntent **mnttbl=getmnttbl(),**ent; 646 struct mntent **mnttbl = getmnttbl (), **ent;
619 for (ent=mnttbl;*ent;ent++) 647 for (ent=mnttbl;*ent;ent++)
620 { 648 {
621 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 649 me = xmalloc (sizeof *me);
622 me->me_devname = strdup ( (*ent)->mt_resource); 650 me->me_devname = xstrdup ( (*ent)->mt_resource);
623 me->me_mountdir = strdup( (*ent)->mt_directory); 651 me->me_mountdir = xstrdup ( (*ent)->mt_directory);
624 me->me_type = strdup ((*ent)->mt_fstype); 652 me->me_type = xstrdup ((*ent)->mt_fstype);
653 me->me_type_malloced = 1;
625 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type); 654 me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
626 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 655 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
627 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ 656 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
@@ -630,7 +659,7 @@ read_filesystem_list (int need_fs_type)
630 *mtail = me; 659 *mtail = me;
631 mtail = &me->me_next; 660 mtail = &me->me_next;
632 } 661 }
633 endmnttbl(); 662 endmnttbl ();
634 } 663 }
635#endif 664#endif
636 665
@@ -679,10 +708,11 @@ read_filesystem_list (int need_fs_type)
679 { 708 {
680 while ((ret = getmntent (fp, &mnt)) == 0) 709 while ((ret = getmntent (fp, &mnt)) == 0)
681 { 710 {
682 me = (struct mount_entry *) malloc (sizeof (struct mount_entry)); 711 me = xmalloc (sizeof *me);
683 me->me_devname = strdup (mnt.mnt_special); 712 me->me_devname = xstrdup (mnt.mnt_special);
684 me->me_mountdir = strdup (mnt.mnt_mountp); 713 me->me_mountdir = xstrdup (mnt.mnt_mountp);
685 me->me_type = strdup (mnt.mnt_fstype); 714 me->me_type = xstrdup (mnt.mnt_fstype);
715 me->me_type_malloced = 1;
686 me->me_dummy = MNT_IGNORE (&mnt) != 0; 716 me->me_dummy = MNT_IGNORE (&mnt) != 0;
687 me->me_remote = ME_REMOTE (me->me_devname, me->me_type); 717 me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
688 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */ 718 me->me_dev = (dev_t) -1; /* Magic; means not known yet. */
@@ -711,21 +741,32 @@ read_filesystem_list (int need_fs_type)
711 int bufsize; 741 int bufsize;
712 char *entries, *thisent; 742 char *entries, *thisent;
713 struct vmount *vmp; 743 struct vmount *vmp;
744 int n_entries;
745 int i;
714 746
715 /* Ask how many bytes to allocate for the mounted filesystem info. */ 747 /* Ask how many bytes to allocate for the mounted filesystem info. */
716 mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize); 748 if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0)
717 entries = malloc (bufsize); 749 return NULL;
750 entries = xmalloc (bufsize);
718 751
719 /* Get the list of mounted filesystems. */ 752 /* Get the list of mounted filesystems. */
720 mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries); 753 n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
754 if (n_entries < 0)
755 {
756 int saved_errno = errno;
757 free (entries);
758 errno = saved_errno;
759 return NULL;
760 }
721 761
722 for (thisent = entries; thisent < entries + bufsize; 762 for (i = 0, thisent = entries;
723 thisent += vmp->vmt_length) 763 i < n_entries;
764 i++, thisent += vmp->vmt_length)
724 { 765 {
725 char *options, *ignore; 766 char *options, *ignore;
726 767
727 vmp = (struct vmount *) thisent; 768 vmp = (struct vmount *) thisent;
728 me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry)); 769 me = xmalloc (sizeof *me);
729 if (vmp->vmt_flags & MNT_REMOTE) 770 if (vmp->vmt_flags & MNT_REMOTE)
730 { 771 {
731 char *host, *path; 772 char *host, *path;
@@ -734,7 +775,7 @@ read_filesystem_list (int need_fs_type)
734 /* Prepend the remote pathname. */ 775 /* Prepend the remote pathname. */
735 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off; 776 host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
736 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off; 777 path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
737 me->me_devname = malloc (strlen (host) + strlen (path) + 2); 778 me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
738 strcpy (me->me_devname, host); 779 strcpy (me->me_devname, host);
739 strcat (me->me_devname, ":"); 780 strcat (me->me_devname, ":");
740 strcat (me->me_devname, path); 781 strcat (me->me_devname, path);
@@ -742,11 +783,12 @@ read_filesystem_list (int need_fs_type)
742 else 783 else
743 { 784 {
744 me->me_remote = 0; 785 me->me_remote = 0;
745 me->me_devname = strdup (thisent + 786 me->me_devname = xstrdup (thisent +
746 vmp->vmt_data[VMT_OBJECT].vmt_off); 787 vmp->vmt_data[VMT_OBJECT].vmt_off);
747 } 788 }
748 me->me_mountdir = strdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off); 789 me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
749 me->me_type = strdup (fstype_to_string (vmp->vmt_gfstype)); 790 me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
791 me->me_type_malloced = 1;
750 options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off; 792 options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off;
751 ignore = strstr (options, "ignore"); 793 ignore = strstr (options, "ignore");
752 me->me_dummy = (ignore 794 me->me_dummy = (ignore
@@ -777,7 +819,8 @@ read_filesystem_list (int need_fs_type)
777 me = mount_list->me_next; 819 me = mount_list->me_next;
778 free (mount_list->me_devname); 820 free (mount_list->me_devname);
779 free (mount_list->me_mountdir); 821 free (mount_list->me_mountdir);
780 /* FIXME: me_type is not always malloced. */ 822 if (mount_list->me_type_malloced)
823 free (mount_list->me_type);
781 free (mount_list); 824 free (mount_list);
782 mount_list = me; 825 mount_list = me;
783 } 826 }