Пример #1
0
struct mount_entry *
read_filesystem_list (int need_fs_type)
{
  struct mount_entry *mount_list;
  struct mount_entry *me;
  struct mount_entry **mtail = &mount_list;

#ifdef MOUNTED_LISTMNTENT
  {
    struct tabmntent *mntlist, *p;
    struct mntent *mnt;
    struct mount_entry *me;

    /* the third and fourth arguments could be used to filter mounts,
       but Crays doesn't seem to have any mounts that we want to
       remove. Specifically, automount create normal NFS mounts.
       */

    if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0)
      return NULL;
    for (p = mntlist; p; p = p->next) {
      mnt = p->ment;
      me = (struct mount_entry*) xmalloc(sizeof (struct mount_entry));
      me->me_devname = xstrdup(mnt->mnt_fsname);
      me->me_mountdir = xstrdup(mnt->mnt_dir);
      me->me_type = xstrdup(mnt->mnt_type);
      me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
      me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
      me->me_dev = -1;
      *mtail = me;
      mtail = &me->me_next;
    }
    freemntlist(mntlist);
  }
#endif

#ifdef MOUNTED_GETMNTENT1	/* 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  {
    struct mntent *mnt;
    char *table = MOUNTED;
    FILE *fp;
    char *devopt;

    fp = setmntent (table, "r");
    if (fp == NULL)
      return NULL;

    while ((mnt = getmntent (fp)))
      {
	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	me->me_devname = xstrdup (mnt->mnt_fsname);
	me->me_mountdir = xstrdup (mnt->mnt_dir);
	me->me_type = xstrdup (mnt->mnt_type);
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	devopt = strstr (mnt->mnt_opts, "dev=");
	if (devopt)
	  {
	    if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
	      me->me_dev = xatoi (devopt + 6);
	    else
	      me->me_dev = xatoi (devopt + 4);
	  }
	else
	  me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }

    if (endmntent (fp) == 0)
      goto free_then_fail;
  }
#endif /* MOUNTED_GETMNTENT1. */

#ifdef MOUNTED_GETMNTINFO	/* 4.4BSD.  */
  {
    struct statfs *fsp;
    int entries;

    entries = getmntinfo (&fsp, MNT_NOWAIT);
    if (entries < 0)
      return NULL;
    for (; entries-- > 0; fsp++)
      {
	char *fs_type = fsp_to_string (fsp);

	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	me->me_devname = xstrdup (fsp->f_mntfromname);
	me->me_mountdir = xstrdup (fsp->f_mntonname);
	me->me_type = fs_type;
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
  }
#endif /* MOUNTED_GETMNTINFO */

#ifdef MOUNTED_GETMNT		/* Ultrix.  */
  {
    int offset = 0;
    int val;
    struct fs_data fsd;

    while (errno = 0,
	   0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
			      (char *) 0)))
      {
	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	me->me_devname = xstrdup (fsd.fd_req.devname);
	me->me_mountdir = xstrdup (fsd.fd_req.path);
	me->me_type = gt_names[fsd.fd_req.fstype];
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = fsd.fd_req.dev;

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
    if (val < 0)
      goto free_then_fail;
  }
#endif /* MOUNTED_GETMNT. */

#if defined (MOUNTED_FS_STAT_DEV) /* BeOS */
  {
    /* The next_dev() and fs_stat_dev() system calls give the list of
       all filesystems, including the information returned by statvfs()
       (fs type, total blocks, free blocks etc.), but without the mount
       point. But on BeOS all filesystems except / are mounted in the
       rootfs, directly under /.
       The directory name of the mount point is often, but not always,
       identical to the volume name of the device.
       We therefore get the list of subdirectories of /, and the list
       of all filesystems, and match the two lists.  */

    DIR *dirp;
    struct rootdir_entry
      {
        char *name;
        dev_t dev;
        ino_t ino;
        struct rootdir_entry *next;
      };
    struct rootdir_entry *rootdir_list;
    struct rootdir_entry **rootdir_tail;
    int32 pos;
    dev_t dev;
    fs_info fi;

    /* All volumes are mounted in the rootfs, directly under /. */
    rootdir_list = NULL;
    rootdir_tail = &rootdir_list;
    dirp = opendir ("/");
    if (dirp)
      {
        struct dirent *d;

        while ((d = readdir (dirp)) != NULL)
          {
            char *name;
            struct stat statbuf;

            if (strcmp (d->d_name, "..") == 0)
              continue;

            if (strcmp (d->d_name, ".") == 0)
              name = xstrdup ("/");
            else
              {
                name = xmalloc (1 + strlen (d->d_name) + 1);
                name[0] = '/';
                strcpy (name + 1, d->d_name);
              }

            if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
              {
                struct rootdir_entry *re;

                re = (struct rootdir_entry *) xmalloc (sizeof (struct rootdir_entry));
                re->name = name;
                re->dev = statbuf.st_dev;
                re->ino = statbuf.st_ino;

                /* Add to the linked list.  */
                *rootdir_tail = re;
                rootdir_tail = &re->next;
              }
            else
              free (name);
          }
        closedir (dirp);
      }
    *rootdir_tail = NULL;

    for (pos = 0; (dev = next_dev (&pos)) >= 0; )
      if (fs_stat_dev (dev, &fi) >= 0)
        {
          /* Note: fi.dev == dev. */
          struct rootdir_entry *re;

          for (re = rootdir_list; re; re = re->next)
            if (re->dev == fi.dev && re->ino == fi.root)
              break;

          me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
          me->me_devname = xstrdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name);
          me->me_mountdir = xstrdup (re != NULL ? re->name : fi.fsh_name);
          me->me_type = xstrdup (fi.fsh_name);
          me->me_dev = fi.dev;
          me->me_dummy = 0;
          me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0;

          /* Add to the linked list. */
          *mtail = me;
          mtail = &me->me_next;
        }
    *mtail = NULL;

    while (rootdir_list != NULL)
      {
        struct rootdir_entry *re = rootdir_list;
        rootdir_list = re->next;
        free (re->name);
        free (re);
      }
  }
#endif /* MOUNTED_FS_STAT_DEV */

#if defined (MOUNTED_GETFSSTAT)	/* __alpha running OSF_1 */
  {
    int numsys, counter, bufsize;
    struct statfs *stats;

    numsys = getfsstat ((struct statfs *)0, 0L, MNT_WAIT);
    if (numsys < 0)
      return (NULL);

    bufsize = (1 + numsys) * sizeof (struct statfs);
    stats = (struct statfs *)xmalloc (bufsize);
    numsys = getfsstat (stats, bufsize, MNT_WAIT);

    if (numsys < 0)
      {
	free (stats);
	return (NULL);
      }

    for (counter = 0; counter < numsys; counter++)
      {
	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	me->me_devname = xstrdup (stats[counter].f_mntfromname);
	me->me_mountdir = xstrdup (stats[counter].f_mntonname);
	me->me_type = mnt_names[stats[counter].f_type];
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }

    free (stats);
  }
#endif /* MOUNTED_GETFSSTAT */

#if defined (MOUNTED_FREAD) || defined (MOUNTED_FREAD_FSTYP) /* SVR[23].  */
  {
    struct mnttab mnt;
    char *table = "/etc/mnttab";
    FILE *fp;

    fp = fopen (table, "r");
    if (fp == NULL)
      return NULL;

    while (fread (&mnt, sizeof mnt, 1, fp) > 0)
      {
	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
# ifdef GETFSTYP			/* SVR3.  */
	me->me_devname = xstrdup (mnt.mt_dev);
# else
	me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
	strcpy (me->me_devname, "/dev/");
	strcpy (me->me_devname + 5, mnt.mt_dev);
# endif
	me->me_mountdir = xstrdup (mnt.mt_filsys);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */
	me->me_type = "";
# ifdef GETFSTYP			/* SVR3.  */
	if (need_fs_type)
	  {
	    struct statfs fsd;
	    char typebuf[FSTYPSZ];

	    if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
		&& sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
	      me->me_type = xstrdup (typebuf);
	  }
# endif
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }

    if (ferror (fp))
      {
	int saved_errno = errno;
	fclose (fp);
	errno = saved_errno;
	goto free_then_fail;
      }

    if (fclose (fp) == EOF)
      goto free_then_fail;
  }
#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */

#ifdef MOUNTED_GETMNTTBL	/* DolphinOS goes it's own way */
  {
    struct mntent **mnttbl=getmnttbl(),**ent;
    for (ent=mnttbl;*ent;ent++)
      {
	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	me->me_devname = xstrdup ( (*ent)->mt_resource);
	me->me_mountdir = xstrdup( (*ent)->mt_directory);
	me->me_type =  xstrdup ((*ent)->mt_fstype);
	me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
	me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
    endmnttbl();
  }
#endif

#ifdef MOUNTED_GETMNTENT2	/* SVR4.  */
  {
    struct mnttab mnt;
    char *table = MNTTAB;
    FILE *fp;
    int ret;
    int lockfd = -1;

# if defined F_RDLCK && defined F_SETLKW
    /* MNTTAB_LOCK is a macro name of our own invention; it's not present in
       e.g. Solaris 2.6.  If the SVR4 folks ever define a macro
       for this file name, we should use their macro name instead.
       (Why not just lock MNTTAB directly?  We don't know.)  */
#  ifndef MNTTAB_LOCK
#   define MNTTAB_LOCK "/etc/.mnttab.lock"
#  endif
    lockfd = open (MNTTAB_LOCK, O_RDONLY);
    if (0 <= lockfd)
      {
	struct flock flock;
	flock.l_type = F_RDLCK;
	flock.l_whence = SEEK_SET;
	flock.l_start = 0;
	flock.l_len = 0;
	while (fcntl (lockfd, F_SETLKW, &flock) == -1)
	  if (errno != EINTR)
	    {
	      int saved_errno = errno;
	      close (lockfd);
	      errno = saved_errno;
	      return NULL;
	    }
      }
    else if (errno != ENOENT)
      return NULL;
# endif

    errno = 0;
    fp = fopen (table, "r");
    if (fp == NULL)
      ret = errno;
    else
      {
	while ((ret = getmntent (fp, &mnt)) == 0)
	  {
	    me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	    me->me_devname = xstrdup (mnt.mnt_special);
	    me->me_mountdir = xstrdup (mnt.mnt_mountp);
	    me->me_type = xstrdup (mnt.mnt_fstype);
	    me->me_dummy = MNT_IGNORE (&mnt) != 0;
	    me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
	    me->me_dev = (dev_t) -1;	/* Magic; means not known yet. */

	    /* Add to the linked list. */
	    *mtail = me;
	    mtail = &me->me_next;
	  }

	ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
      }

    if (0 <= lockfd && close (lockfd) != 0)
      ret = errno;

    if (0 <= ret)
      {
	errno = ret;
	goto free_then_fail;
      }
  }
#endif /* MOUNTED_GETMNTENT2.  */

#ifdef MOUNTED_VMOUNT		/* AIX.  */
  {
    int bufsize;
    char *entries, *thisent;
    struct vmount *vmp;

    /* Ask how many bytes to allocate for the mounted filesystem info.  */
    mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize);
    entries = xmalloc (bufsize);

    /* Get the list of mounted filesystems.  */
    mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);

    for (thisent = entries; thisent < entries + bufsize;
	 thisent += vmp->vmt_length)
      {
	char *options, *ignore;

	vmp = (struct vmount *) thisent;
	me = (struct mount_entry *) xmalloc (sizeof (struct mount_entry));
	if (vmp->vmt_flags & MNT_REMOTE)
	  {
	    char *host, *path;

	    me->me_remote = 1;
	    /* Prepend the remote pathname.  */
	    host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
	    path = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
	    me->me_devname = xmalloc (strlen (host) + strlen (path) + 2);
	    strcpy (me->me_devname, host);
	    strcat (me->me_devname, ":");
	    strcat (me->me_devname, path);
	  }
	else
	  {
	    me->me_remote = 0;
	    me->me_devname = xstrdup (thisent +
				      vmp->vmt_data[VMT_OBJECT].vmt_off);
	  }
	me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
	me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
	options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off;
	ignore = strstr (options, "ignore");
	me->me_dummy = (ignore
			&& (ignore == options || ignore[-1] == ',')
			&& (ignore[sizeof "ignore" - 1] == ','
			    || ignore[sizeof "ignore" - 1] == '\0'));
	me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want.  */

	/* Add to the linked list. */
	*mtail = me;
	mtail = &me->me_next;
      }
    free (entries);
  }
#endif /* MOUNTED_VMOUNT. */

  *mtail = NULL;
  return mount_list;


 free_then_fail:
  {
    int saved_errno = errno;
    *mtail = NULL;

    while (mount_list)
      {
	me = mount_list->me_next;
	free (mount_list->me_devname);
	free (mount_list->me_mountdir);
	/* FIXME: me_type is not always malloced.  */
	free (mount_list);
	mount_list = me;
      }

    errno = saved_errno;
    return NULL;
  }
}
Пример #2
0
/*
 * Given a full path to a file, translate into a dataset name and a relative
 * path within the dataset.  'dataset' must be at least MAXNAMELEN characters,
 * and 'relpath' must be at least MAXPATHLEN characters.  We also pass a stat
 * buffer, which we need later to get the object ID.
 */
static int
parse_pathname(const char *inpath, char *dataset, char *relpath,
    struct stat *statbuf)
{
	struct extmnttab mp;
	FILE *fp;
	int match;
	const char *rel;
	char fullpath[MAXPATHLEN];

	compress_slashes(inpath, fullpath);

	if (fullpath[0] != '/') {
		(void) fprintf(stderr, "invalid object '%s': must be full "
		    "path\n", fullpath);
		usage();
		return (-1);
	}

	if (strlen(fullpath) >= MAXPATHLEN) {
		(void) fprintf(stderr, "invalid object; pathname too long\n");
		return (-1);
	}

	if (stat(fullpath, statbuf) != 0) {
		(void) fprintf(stderr, "cannot open '%s': %s\n",
		    fullpath, strerror(errno));
		return (-1);
	}

#ifdef HAVE_SETMNTENT
	if ((fp = setmntent(MNTTAB, "r")) == NULL) {
#else
	if ((fp = fopen(MNTTAB, "r")) == NULL) {
#endif
		(void) fprintf(stderr, "cannot open /etc/mtab\n");
		return (-1);
	}

	match = 0;
	while (getextmntent(fp, &mp, sizeof (mp)) == 0) {
		if (makedev(mp.mnt_major, mp.mnt_minor) == statbuf->st_dev) {
			match = 1;
			break;
		}
	}

	if (!match) {
		(void) fprintf(stderr, "cannot find mountpoint for '%s'\n",
		    fullpath);
		return (-1);
	}

	if (strcmp(mp.mnt_fstype, MNTTYPE_ZFS) != 0) {
		(void) fprintf(stderr, "invalid path '%s': not a ZFS "
		    "filesystem\n", fullpath);
		return (-1);
	}

	if (strncmp(fullpath, mp.mnt_mountp, strlen(mp.mnt_mountp)) != 0) {
		(void) fprintf(stderr, "invalid path '%s': mountpoint "
		    "doesn't match path\n", fullpath);
		return (-1);
	}

	(void) strcpy(dataset, mp.mnt_special);

	rel = fullpath + strlen(mp.mnt_mountp);
	if (rel[0] == '/')
		rel++;
	(void) strcpy(relpath, rel);

	return (0);
}
#endif

//From FreeBSD
static int
parse_pathname(const char *inpath, char *dataset, char *relpath,
    struct stat *statbuf)
{
        struct statfs sfs;
        const char *rel;
        char fullpath[MAXPATHLEN];

        compress_slashes(inpath, fullpath);

        if (fullpath[0] != '/') {
                (void) fprintf(stderr, "invalid object '%s': must be full "
                    "path\n", fullpath);
                usage();
                return (-1);
        }

        if (strlen(fullpath) >= MAXPATHLEN) {
                (void) fprintf(stderr, "invalid object; pathname too long\n");
                return (-1);
        }

        if (stat(fullpath, statbuf) != 0) {
                (void) fprintf(stderr, "cannot open '%s': %s\n",
                    fullpath, strerror(errno));
                return (-1);
        }

        if (statfs(fullpath, &sfs) == -1) {
                (void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n",
                    fullpath, strerror(errno));
                return (-1);
        }

        if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) {
                (void) fprintf(stderr, "invalid path '%s': not a ZFS "
                    "filesystem\n", fullpath);
                return (-1);
        }

        if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) {
                (void) fprintf(stderr, "invalid path '%s': mountpoint "
                    "doesn't match path\n", fullpath);
                return (-1);
        }

        (void) strcpy(dataset, sfs.f_mntfromname);

        rel = fullpath + strlen(sfs.f_mntonname);
        if (rel[0] == '/')
                rel++;
        (void) strcpy(relpath, rel);

        return (0);
}

/*
 * Convert from a (dataset, path) pair into a (objset, object) pair.  Note that
 * we grab the object number from the inode number, since looking this up via
 * libzpool is a real pain.
 */
/* ARGSUSED */
static int
object_from_path(const char *dataset, const char *path, struct stat *statbuf,
    zinject_record_t *record)
{
	objset_t *os;
	int err;

	/*
	 * Before doing any libzpool operations, call sync() to ensure that the
	 * on-disk state is consistent with the in-core state.
	 */
	sync();

	err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, B_FALSE, FTAG, &os);
	if (err != 0) {
		(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
		    dataset, strerror(err));
		return (-1);
	}

	record->zi_objset = dmu_objset_id(os);
	record->zi_object = statbuf->st_ino;

	dmu_objset_disown(os, B_FALSE, FTAG);

	return (0);
}
Пример #3
0
static void
winCheckMount(void)
{
  FILE *mnt;
  struct mntent *ent;

  enum { none = 0, sys_root, user_root, sys_tmp, user_tmp } 
    level = none, curlevel;
  BOOL binary = TRUE;

  mnt = setmntent("/etc/mtab", "r");
  if (mnt == NULL)
  {
    ErrorF("setmntent failed");
    return;
  }

  while ((ent = getmntent(mnt)) != NULL)
  {
    BOOL system = (winCheckMntOpt(ent, "user") != NULL);
    BOOL root = (strcmp(ent->mnt_dir, "/") == 0);
    BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0);
    
    if (system)
    {
      if (root)
        curlevel = sys_root;
      else if (tmp)
        curlevel = sys_tmp;
      else
        continue;
    }
    else
    {
      if (root)
        curlevel = user_root;
      else if (tmp) 
        curlevel = user_tmp;
      else
        continue;
    }

    if (curlevel <= level)
      continue;
    level = curlevel;

    if ((winCheckMntOpt(ent, "binary") == NULL) &&
        (winCheckMntOpt(ent, "binmode") == NULL))
      binary = FALSE;
    else
      binary = TRUE;
  }
    
  if (endmntent(mnt) != 1)
  {
    ErrorF("endmntent failed");
    return;
  }
  
 if (!binary) 
   winMsg(X_WARNING, "/tmp mounted in textmode\n");
}
Пример #4
0
int ecryptfs_mount(char *source, char *target, unsigned long flags, char *opts)
{
	FILE *mtab_fd = NULL;
	struct mntent mountent;

#if 1  // sw.yoo_20120110 - realpath 사용 포맷을 바꿈

	char fullpath_source[PATH_MAX];
	char fullpath_target[PATH_MAX];
#else
	char *fullpath_source = NULL;
	char *fullpath_target = NULL;
#endif
	int rc;

 printf("[eCryptfs]:source=%s, target=%s, opts = %s, %s, %d \n", source, target, opts, __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print
	mountent.mnt_opts = NULL;
	if (!source) {
		rc = -EINVAL;
		syslog(LOG_ERR, "Invalid source directory\n");
		goto out;
	}
printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print
	if (!target) {
		rc = -EINVAL;
		syslog(LOG_ERR, "Invalid target directory\n");
		goto out;
	}
printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print
	if (strlen(opts) > 200) {
		rc = -EINVAL;
		syslog(LOG_ERR, "Invalid mount options length\n");
		goto out;
	}
printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print
#if 1 // sw.yoo_20120110 - realpath 사용 포맷을 바꿈
	if (!realpath(source, fullpath_source)) {
		rc = -errno;
		syslog(LOG_ERR, "could not resolve full path for source %s [%d]",
			source, -errno);
		goto out;
	}
#else
	fullpath_source = realpath(source, NULL);
	if (!fullpath_source) {
		rc = -errno;
		syslog(LOG_ERR, "could not resolve full path for source %s [%d]",
			source, -errno);
		goto out;
	}
#endif
printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print
#if 1 // sw.yoo_20120110 - realpath 사용 포맷을 바꿈
	if (!realpath(target, fullpath_target)) {
		rc = -errno;
		syslog(LOG_ERR, "could not resolve full path for target %s [%d]",
			target, -errno);
		goto out;
	}
#else
	fullpath_target = realpath(target, NULL);

	if (!fullpath_target) {
		rc = -errno;
		syslog(LOG_ERR, "could not resolve full path for target %s [%d]",
			target, -errno);
		goto out;
	}
#endif
printf("[eCryptfs]:s=%s,d=%s,flags=0x%x, opts=%s\n", fullpath_source,fullpath_target,flags,opts); //sw.yoo_201120110 - debug print
	if (mount(fullpath_source, fullpath_target, "ecryptfs", flags, opts)) {
		rc = -errno;
		syslog(LOG_ERR, "Failed to perform eCryptfs mount: [%m]\n");
		goto out;
	}
#if 0   //sw.yoo_20120106 - mntent.h 관련 함수 사용 막음
	mtab_fd = setmntent("/etc/mtab", "a");
	if (!mtab_fd) {
		rc = -EACCES;
		syslog(LOG_ERR, "Failed to update the mount table\n");
		goto out;
	}
	mountent.mnt_fsname = fullpath_source;
	mountent.mnt_dir = fullpath_target;
	mountent.mnt_type = "ecryptfs";
	/* we need the following byte count:
	 * 200 max for opts
	 * 23  max for strings below
	 * 1   the final \0
	 */
	mountent.mnt_opts = malloc(224);
	if (!mountent.mnt_opts) {
		rc = -ENOMEM;
		syslog(LOG_ERR, "Failed to allocate memory for mount "
		       "options\n");
		goto out;
	}
	memset(mountent.mnt_opts, 0, 224);
	/* reporting the right mount opts */
	if (flags & MS_RDONLY)
		strcat(mountent.mnt_opts,"ro");
	else
		strcat(mountent.mnt_opts,"rw");
	if (flags & MS_NOEXEC)
		strcat(mountent.mnt_opts,",noexec");
	if (flags & MS_NOSUID)
		strcat(mountent.mnt_opts,",nosuid");
	if (flags & MS_NODEV)
		strcat(mountent.mnt_opts,",nodev");
	if (opts) {
		strcat(mountent.mnt_opts, ",");
		strcat(mountent.mnt_opts, opts);
	}
	mountent.mnt_freq = 0;
	mountent.mnt_passno = 0;
	if (addmntent(mtab_fd, &mountent)) {
		rc = -EIO;
		syslog(LOG_ERR, "Failed to write to the mount "
		       "table\n");
		goto out;
	}
#endif
	rc = 0;
out:
#if 0
	free(fullpath_source);
	free(fullpath_target);
#endif
#if 0  //sw.yoo_20120106 - mntent.h 관련 함수 사용 막음
	free(mountent.mnt_opts);
	if (mtab_fd)
		endmntent(mtab_fd);
#endif
	return rc;
	printf("[eCryptfs]: %s, %d \n", __FUNCTION__, __LINE__); //sw.yoo_201120110 - debug print
}
Пример #5
0
/* returns <0 if error                            */
int get_device( char *path, char *device )
{

#if ( !defined( __sun ) )
  FILE	*tmp_streamin;
  char	tmp_bufferin[ MAX_STRING ];
  char  tmp_path[ 256 ];
  int   l = 0;

#endif

#if (defined(__linux__))
  struct mntent* lmount_entry;
#endif

#if ( defined( __sun ) )
  FILE  *mnttab_fp;
  char *mnt_special;
  int mntcheck;
  char *new_device;
#endif

  char  *pointer;
  char  *k;
  bool  mounted = FALSE;

#ifdef USE_STATFS_FOR_DEV
  struct statfs buf;
#endif
#ifdef USE_STATVFS_FOR_DEV
  struct statvfs buf;
#endif


  /* the string should have no trailing / */
  if( path[ ( strlen( path ) - 1 ) ] == '/' )
  {
      path[ ( strlen( path ) - 1 ) ] = '\0' ;
  }

  /* remove video_ts if given */
  if( ( pointer = strstr( path, "/video_ts" ) ) || 
      ( pointer = strstr( path, "/VIDEO_TS" ) ) )
  {
      *pointer = '\0';
  }

  /* check if it is given as /dev/xxx already */
  if( strstr( path, "/dev/" ) )
  {
      strcpy( device, path );
  }
  else
  {

    /*
     *look through /etc/mtab to see if it's actually mounted
     */
#if ( defined( USE_STATFS_FOR_DEV ) || defined( USE_STATVFS_FOR_DEV ) ) 

#ifdef USE_STATFS_FOR_DEV
    if( !statfs( path, &buf ) )
#else
    if( !statvfs( path, &buf ) )
#endif
      {
       if( !strcmp( path, buf.f_mntonname ) )
         {
           mounted = TRUE;
#if defined(__FreeBSD__) && (__FreeBSD_Version > 500000)
          strcpy(device, buf.f_mntfromname);
#else
	   strcpy(device, "/dev/r");
	   strcat(device, buf.f_mntfromname + 5);
#endif
	   return mounted;
         }
         strcpy(device, buf.f_mntfromname);
      }
    else
      {
       fprintf( stderr, _("[Error] Error while reading filesystem info") );
       return -1;
      }
#elif ( defined( __sun ) )

    struct mnttab mount_entry;
    int           mntcheck;
 
    if ( ( mnttab_fp = fopen( "/etc/mnttab", "r" ) ) == NULL )
      {
	fprintf( stderr, _(" [Error] Could not open mnttab for searching!\n") );
	fprintf( stderr, _(" [Error] error: %s\n"), strerror( errno ) );
	return -1;
      }

    while ( ( mntcheck = getmntent( mnttab_fp, &mount_entry ) ) == 0 )
      {
	/* check to see if our path is this entry */
	if ( strcmp( path, mount_entry.mnt_mountp ) == 0 )
	  {
	    char *new_device, *mnt_special;
	    if ( strstr( mount_entry.mnt_special, "/dsk/" ) == NULL )
	      {
		fprintf( stderr, _("[Error] %s doesn't look like a disk device to me"),
			 mount_entry.mnt_special );
		return -1;
	      }
	    /* we actually want the raw device name */

	    mnt_special = malloc( strlen( mount_entry.mnt_special ) + 1 );
	    new_device = malloc( strlen( mount_entry.mnt_special ) + 2 );
	    strcpy( mnt_special, mount_entry.mnt_special );
	    strcpy( new_device, mnt_special );
	    strcpy( strstr( new_device, "/dsk/" ), "" );
	    strcat( new_device, "/rdsk/" );
	    strcat( new_device,
		    strstr( mnt_special, "/dsk/" ) + strlen( "/dsk/" ) );
	    strncpy( device, new_device, sizeof(device)-1 );
	    free( mnt_special );
	    free( new_device );
	    mounted = TRUE;
	    break;
	  }
      }
    if ( mntcheck > 0 )
      {
         fprintf( stderr, _("[Error] Encountered error in reading mnttab file\n") );
         fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) );
         return -1;
      }
    else if ( mntcheck == -1 )
      {
         fprintf( stderr, _("[Error] Did not find mount %s in mnttab!\n"), path );
         return -1;
      }
#else
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
this is the code for the other-OSs, not solaris*/

#if (defined(__linux__)) 
    if ((tmp_streamin = setmntent("/etc/mtab", "r"))){

	while ((lmount_entry = getmntent(tmp_streamin))){
	    if (strcmp(lmount_entry->mnt_dir, path) == 0){
		/* Found the mount point */
	      fprintf ( stderr, "[Info] Device %s mounted on %s\n", lmount_entry->mnt_fsname, lmount_entry->mnt_dir);
		strcpy(device, lmount_entry->mnt_fsname);
		mounted = TRUE;
		break;
	    }
	}
	endmntent(tmp_streamin);
	if (mounted) 
            {
		/* device was set from /etc/mtab, no need to further check
		 * /etc/fstab */
		return mounted;
            }
    }
#endif

    
    if( ( tmp_streamin = fopen( "/etc/mtab", "r" ) ) )
      {
	strcpy( tmp_path, path );
	strcat( tmp_path, " " ); /* otherwise it would detect that e.g. 
				  /cdrom is mounted even if only/cdrom1 is 
				  mounted */ 

	memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) );
	while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin )) 
          {
	    if( strstr( tmp_bufferin, tmp_path ) )
              {
		mounted = TRUE;
	      }
	  }
	fclose( tmp_streamin );
      }
    else
      {
	fprintf( stderr, _("[Error] Could not read /etc/mtab!\n") );
	fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) );
	return -1;
      }  
#endif

#if defined( __sun )
  }
#else

    
    /*
     *read the device out of /etc/fstab 
     */

    if( ( tmp_streamin = fopen( "/etc/fstab", "r" ) ) )
      {
	strcpy(tmp_path, path);

	memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) );
	while( fgets( tmp_bufferin, MAX_STRING, tmp_streamin ) ) 
	  {
	    if( ( pointer = strstr( tmp_bufferin, tmp_path ) ) )
              {
		if( isgraph( ( int ) *( pointer + strlen( tmp_path ) ) ) )
		  break; /* there is something behind the path name, 
			    for instance like it would find /cdrom but 
			    also /cdrom1 since /cdrom is a subset of /cdrom1 */
		/*isblank should work too but how do you do that with 
		  the "gnu extension"? (man isblank) */

		if( ( k = strstr( tmp_bufferin, "/dev/" ) ) == NULL )
		  {
		    fprintf( stderr, _("[Error] Weird, no /dev/ entry found in the line where iso9660 or udf gets mentioned in /etc/fstab\n") );
		    return -1;
		  }
		l=0;

		while( isgraph( (int) *(k) ) )
	          {
		    device[l] = *(k);
		    if( device[l] == ',' )
		      break;
		    l++;
		    k++;
	          }
		if( isdigit( ( int) device[l-1] ) )
	          {
                 if( strstr( device, "hd" ) )
	              fprintf( stderr, _("[Hint] Hmm, the last char in the device path (%s) that gets mounted to %s is a number.\n"), device, path);
	          }
		device[l] = '\0';
	      }
	    memset( tmp_bufferin, 0, MAX_STRING * sizeof( char ) );
          }
          fclose( tmp_streamin );
	  if( !strstr( device, "/dev" ) )
	    {
	      fprintf( stderr, _("[Error] Could not find the provided path (%s), typo?\n"),path);
	      device[0] = '\0';
	      return -1;
	    }
      }
    else
      {
	fprintf( stderr, _("[Error] Could not read /etc/fstab!") );
	fprintf( stderr, _("[Error] error: %s\n"), strerror( errno ) );
	device[0] = '\0';
	return -1;
      }
  }
Пример #6
0
/**
 * build the export entry
 */
fsal_status_t GPFSFSAL_BuildExportContext(fsal_export_context_t *export_context, /* OUT */
                                      fsal_path_t * p_export_path,      /* IN */
                                      char *fs_specific_options /* IN */
    )
{
  int                  rc, fd, mntexists;
  FILE               * fp;
  struct mntent      * p_mnt;
  char               * mnt_dir = NULL;
  struct statfs        stat_buf;
  gpfs_fsal_up_ctx_t * gpfs_fsal_up_ctx;
  bool_t               start_fsal_up_thread = FALSE;

  fsal_status_t status;
  fsal_op_context_t op_context;
  gpfsfsal_export_context_t *p_export_context = (gpfsfsal_export_context_t *)export_context;

  /* Make sure the FSAL UP context list is initialized */
  if(glist_null(&gpfs_fsal_up_ctx_list))
    init_glist(&gpfs_fsal_up_ctx_list);

  /* sanity check */
  if((p_export_context == NULL) || (p_export_path == NULL))
    {
      LogCrit(COMPONENT_FSAL,
              "NULL mandatory argument passed to %s()", __FUNCTION__);
      Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_BuildExportContext);
    }

  /* open mnt file */
  fp = setmntent(MOUNTED, "r");

  if(fp == NULL)
    {
      rc = errno;
      LogCrit(COMPONENT_FSAL, "Error %d in setmntent(%s): %s", rc, MOUNTED,
                      strerror(rc));
      Return(posix2fsal_error(rc), rc, INDEX_FSAL_BuildExportContext);
    }

  /* Check if mount point is really a gpfs share. If not, we can't continue.*/
  mntexists = 0;
  while((p_mnt = getmntent(fp)) != NULL)
    if(p_mnt->mnt_dir != NULL  && p_mnt->mnt_type != NULL)
      /* There is probably a macro for "gpfs" type ... not sure where it is. */
      if (strncmp(p_mnt->mnt_type, "gpfs", 4) == 0)
        {
          LogFullDebug(COMPONENT_FSAL,
                       "Checking Export Path %s against GPFS fs %s",
                       p_export_path->path, p_mnt->mnt_dir);

          /* If export path is shorter than fs path, then this isn't a match */
          if(strlen(p_export_path->path) < strlen(p_mnt->mnt_dir))
            continue;

          /* If export path doesn't have a path separator after mnt_dir, then it
           * isn't a proper sub-directory of mnt_dir.
           */
          if((p_export_path->path[strlen(p_mnt->mnt_dir)] != '/') &&
             (p_export_path->path[strlen(p_mnt->mnt_dir)] != '\0'))
            continue;

          if (strncmp(p_mnt->mnt_dir, p_export_path->path, strlen(p_mnt->mnt_dir)) == 0)
            {
              mnt_dir = gsh_strdup(p_mnt->mnt_dir);
              mntexists = 1;
              break;
            }
        }
  
  endmntent(fp);

  if (mntexists == 0)
    {
      LogMajor(COMPONENT_FSAL,
               "GPFS mount point %s does not exist.",
               p_export_path->path);
      gsh_free(mnt_dir);
      ReturnCode(ERR_FSAL_INVAL, 0);
    }

  /* save file descriptor to root of GPFS share */
  fd = open(p_export_path->path, O_RDONLY | O_DIRECTORY);
  if(fd < 0)
    {
      if(errno == ENOENT)
        LogMajor(COMPONENT_FSAL,
                 "GPFS export path %s does not exist.",
                 p_export_path->path);
      else if (errno == ENOTDIR)
        LogMajor(COMPONENT_FSAL,
                 "GPFS export path %s is not a directory.",
                 p_export_path->path);
      else
        LogMajor(COMPONENT_FSAL,
                 "Could not open GPFS export path %s: rc = %d(%s)",
                 p_export_path->path, errno, strerror(errno));

      if(mnt_dir != NULL)
        gsh_free(mnt_dir);

      ReturnCode(ERR_FSAL_INVAL, 0);
    }

  p_export_context->mount_root_fd = fd;

  LogFullDebug(COMPONENT_FSAL,
               "GPFSFSAL_BuildExportContext: %d",
               p_export_context->mount_root_fd);

  /* Save pointer to fsal_staticfsinfo_t in export context */
  p_export_context->fe_static_fs_info = &global_fs_info;

  /* save filesystem ID */
  rc = statfs(p_export_path->path, &stat_buf);

  if(rc)
    {
      close(fd);
      LogMajor(COMPONENT_FSAL,
               "statfs call failed on file %s: %d(%s)",
               p_export_path->path, errno, strerror(errno));

      if(mnt_dir != NULL)
        gsh_free(mnt_dir);

      ReturnCode(ERR_FSAL_INVAL, 0);
    }

  p_export_context->fsid[0] = stat_buf.f_fsid.__val[0];
  p_export_context->fsid[1] = stat_buf.f_fsid.__val[1];

  /* save file handle to root of GPFS share */
  op_context.export_context = export_context;

  // op_context.credential = ???
  status = fsal_internal_get_handle(&op_context,
                                    p_export_path,
                                    (fsal_handle_t *)(&(p_export_context->mount_root_handle)));

  if(FSAL_IS_ERROR(status))
    {
      close(p_export_context->mount_root_fd);
      LogMajor(COMPONENT_FSAL,
               "FSAL BUILD EXPORT CONTEXT: ERROR: Conversion from gpfs filesystem root path to handle failed : %d",
               status.minor);

      if(mnt_dir != NULL)
        gsh_free(mnt_dir);

      ReturnCode(ERR_FSAL_INVAL, 0);
    }

  gpfs_fsal_up_ctx = gpfsfsal_find_fsal_up_context(p_export_context);

  if(gpfs_fsal_up_ctx == NULL)
    {
      gpfs_fsal_up_ctx = gsh_calloc(1, sizeof(gpfs_fsal_up_ctx_t));

      if(gpfs_fsal_up_ctx == NULL || mnt_dir == NULL)
        {
          LogFatal(COMPONENT_FSAL,
                   "Out of memory can not continue.");
        }

      /* Initialize the gpfs_fsal_up_ctx */
      init_glist(&gpfs_fsal_up_ctx->gf_exports);
      gpfs_fsal_up_ctx->gf_fs = mnt_dir;
      gpfs_fsal_up_ctx->gf_fsid[0] = p_export_context->fsid[0];
      gpfs_fsal_up_ctx->gf_fsid[1] = p_export_context->fsid[1];

      /* Add it to the list of contexts */
      glist_add_tail(&gpfs_fsal_up_ctx_list, &gpfs_fsal_up_ctx->gf_list);

      start_fsal_up_thread = TRUE;
    }
  else
    {
      if(mnt_dir != NULL)
        gsh_free(mnt_dir);
    }

  /* Add this export context to the list for it's gpfs_fsal_up_ctx */
  glist_add_tail(&gpfs_fsal_up_ctx->gf_exports, &p_export_context->fe_list);
  p_export_context->fe_fsal_up_ctx = gpfs_fsal_up_ctx;

  if(start_fsal_up_thread)
    {
      pthread_attr_t attr_thr;

      memset(&attr_thr, 0, sizeof(attr_thr));

      /* Initialization of thread attributes borrowed from nfs_init.c */
      if(pthread_attr_init(&attr_thr) != 0)
        LogCrit(COMPONENT_THREAD, "can't init pthread's attributes");

      if(pthread_attr_setscope(&attr_thr, PTHREAD_SCOPE_SYSTEM) != 0)
        LogCrit(COMPONENT_THREAD, "can't set pthread's scope");

      if(pthread_attr_setdetachstate(&attr_thr, PTHREAD_CREATE_JOINABLE) != 0)
        LogCrit(COMPONENT_THREAD, "can't set pthread's join state");

      if(pthread_attr_setstacksize(&attr_thr, 2116488) != 0)
        LogCrit(COMPONENT_THREAD, "can't set pthread's stack size");

      rc = pthread_create(&gpfs_fsal_up_ctx->gf_thread,
                          &attr_thr,
                          GPFSFSAL_UP_Thread,
                          gpfs_fsal_up_ctx);

      if(rc != 0)
        {
          LogFatal(COMPONENT_THREAD,
                   "Could not create GPFSFSAL_UP_Thread, error = %d (%s)",
                   errno, strerror(errno));
        }
    }

  Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_BuildExportContext);
}
Пример #7
0
RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType)
{
    *penmType = RTFSTYPE_UNKNOWN;

    /*
     * Validate input.
     */
    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
    AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER);

    /*
     * Convert the path and query the stats.
     * We're simply return the device id.
     */
    char const *pszNativeFsPath;
    int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
    if (RT_SUCCESS(rc))
    {
        struct stat Stat;
        if (!stat(pszNativeFsPath, &Stat))
        {
#if defined(RT_OS_LINUX)
            FILE *mounted = setmntent("/proc/mounts", "r");
            if (!mounted)
                mounted = setmntent("/etc/mtab", "r");
            if (mounted)
            {
                char            szBuf[1024];
                struct stat     mntStat;
                struct mntent   mntEnt;
                while (getmntent_r(mounted, &mntEnt, szBuf, sizeof(szBuf)))
                {
                    if (!stat(mntEnt.mnt_dir, &mntStat))
                    {
                        if (mntStat.st_dev == Stat.st_dev)
                        {
                            if (!strcmp("ext4", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT4;
                            else if (!strcmp("ext3", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT3;
                            else if (!strcmp("ext2", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT2;
                            else if (!strcmp("jfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_JFS;
                            else if (!strcmp("xfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_XFS;
                            else if (!strcmp("btrfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_BTRFS;
                            else if (   !strcmp("vfat", mntEnt.mnt_type)
                                     || !strcmp("msdos", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_FAT;
                            else if (!strcmp("ntfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NTFS;
                            else if (!strcmp("hpfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_HPFS;
                            else if (!strcmp("ufs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_UFS;
                            else if (!strcmp("tmpfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_TMPFS;
                            else if (!strcmp("hfsplus", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_HFS;
                            else if (!strcmp("udf", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_UDF;
                            else if (!strcmp("iso9660", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_ISO9660;
                            else if (!strcmp("smbfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_SMBFS;
                            else if (!strcmp("cifs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_CIFS;
                            else if (!strcmp("nfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NFS;
                            else if (!strcmp("nfs4", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NFS;
                            else if (!strcmp("ocfs2", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_OCFS2;
                            else if (!strcmp("sysfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_SYSFS;
                            else if (!strcmp("proc", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_PROC;
                            else if (   !strcmp("fuse", mntEnt.mnt_type)
                                     || !strncmp("fuse.", mntEnt.mnt_type, 5)
                                     || !strcmp("fuseblk", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_FUSE;
                            else
                            {
                                /* sometimes there are more than one entry for the same partition */
                                continue;
                            }
                            break;
                        }
                    }
                }
                endmntent(mounted);
            }

#elif defined(RT_OS_SOLARIS)
            if (!strcmp("zfs", Stat.st_fstype))
                *penmType = RTFSTYPE_ZFS;
            else if (!strcmp("ufs", Stat.st_fstype))
                *penmType = RTFSTYPE_UFS;
            else if (!strcmp("nfs", Stat.st_fstype))
                *penmType = RTFSTYPE_NFS;

#elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
            struct statfs statfsBuf;
            if (!statfs(pszNativeFsPath, &statfsBuf))
            {
                if (!strcmp("hfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_HFS;
                else if (   !strcmp("fat", statfsBuf.f_fstypename)
                         || !strcmp("msdos", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_FAT;
                else if (!strcmp("ntfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_NTFS;
                else if (!strcmp("autofs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_AUTOFS;
                else if (!strcmp("devfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_DEVFS;
                else if (!strcmp("nfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_NFS;
                else if (!strcmp("ufs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_UFS;
                else if (!strcmp("zfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_ZFS;
            }
            else
                rc = RTErrConvertFromErrno(errno);
#endif
        }
        else
            rc = RTErrConvertFromErrno(errno);
        rtPathFreeNative(pszNativeFsPath, pszFsPath);
    }

    return rc;
}
Пример #8
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
  uid_t euser_id;
  int r;
  struct dqblk D;
  struct fs_disk_quota        F;
  SMB_STRUCT_STAT S;
  FILE *fp;
  struct mntent *mnt;
  SMB_DEV_T devno;
  int found;
  
  /* find the block device file */
  
  if ( sys_stat(path, &S) == -1 ) {
    return(False) ;
  }

  devno = S.st_dev ;
  
  fp = setmntent(MOUNTED,"r");
  found = False ;
  
  while ((mnt = getmntent(fp))) {
    if ( sys_stat(mnt->mnt_dir,&S) == -1 )
      continue ;
    if (S.st_dev == devno) {
      found = True ;
      break ;
    }
  }
  endmntent(fp) ;
  
  if (!found) {
    return(False);
  }

  euser_id=geteuid();
  save_re_uid();
  set_effective_uid(0);  

  /* Use softlimit to determine disk space, except when it has been exceeded */

  *bsize = 512;

  if ( 0 == strcmp ( mnt->mnt_type, "efs" ))
  {
    r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);

    restore_re_uid();

    if (r==-1)
      return(False);
        
    /* Use softlimit to determine disk space, except when it has been exceeded */
    if (
        (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
        (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
        (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) ||
        (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit)
       )
    {
      *dfree = 0;
      *dsize = D.dqb_curblocks;
    }
    else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
    {
      return(False);
    }
    else 
    {
      *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
      *dsize = D.dqb_bsoftlimit;
    }

  }
  else if ( 0 == strcmp ( mnt->mnt_type, "xfs" ))
  {
    r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);

    restore_re_uid();

    if (r==-1)
      return(False);
        
    /* Use softlimit to determine disk space, except when it has been exceeded */
    if (
        (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
        (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) ||
        (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) ||
        (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit)
       )
    {
      *dfree = 0;
      *dsize = F.d_bcount;
    }
    else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
    {
      return(False);
    }
    else 
    {
      *dfree = (F.d_blk_softlimit - F.d_bcount);
      *dsize = F.d_blk_softlimit;
    }

  }
  else
  {
	  restore_re_uid();
	  return(False);
  }

  return (True);

}
Пример #9
0
static int may_unmount(const char *mnt, int quiet)
{
	struct mntent *entp;
	FILE *fp;
	const char *user = NULL;
	char uidstr[32];
	unsigned uidlen = 0;
	int found;
	const char *mtab = _PATH_MOUNTED;

	user = get_user_name();
	if (user == NULL)
		return -1;

	fp = setmntent(mtab, "r");
	if (fp == NULL) {
		fprintf(stderr, "%s: failed to open %s: %s\n", progname, mtab,
			strerror(errno));
		return -1;
	}

	uidlen = sprintf(uidstr, "%u", getuid());

	found = 0;
	while ((entp = getmntent(fp)) != NULL) {
		if (!found && strcmp(entp->mnt_dir, mnt) == 0 &&
		    (strcmp(entp->mnt_type, "fuse") == 0 ||
		     strcmp(entp->mnt_type, "fuseblk") == 0 ||
		     strncmp(entp->mnt_type, "fuse.", 5) == 0 ||
		     strncmp(entp->mnt_type, "fuseblk.", 8) == 0)) {
			char *p = strstr(entp->mnt_opts, "user="******"user_id=")) &&
				 (p == entp->mnt_opts ||
				  *(p-1) == ',') &&
				 strncmp(p + 8, uidstr, uidlen) == 0 &&
				 (*(p+8+uidlen) == ',' ||
				  *(p+8+uidlen) == '\0')) {
				found = 1;
				break;
			}
		}
	}
	endmntent(fp);

	if (!found) {
		if (!quiet)
			fprintf(stderr,
				"%s: entry for %s not found in %s\n",
				progname, mnt, mtab);
		return -1;
	}

	return 0;
}
Пример #10
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
  struct mntent *mnt;
  FILE *fd;
  SMB_STRUCT_STAT sbuf;
  SMB_DEV_T devno ;
  static SMB_DEV_T devno_cached = 0 ;
  static pstring name;
  struct q_request request ;
  struct qf_header header ;
  static int quota_default = 0 ;
  int found ;
  
  if ( sys_stat(path,&sbuf) == -1 )
    return(False) ;
  
  devno = sbuf.st_dev ;
  
  if ( devno != devno_cached ) {
    
    devno_cached = devno ;
    
    if ((fd = setmntent(KMTAB)) == NULL)
      return(False) ;
    
    found = False ;
    
    while ((mnt = getmntent(fd)) != NULL) {
      
      if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
	continue ;
      
      if (sbuf.st_dev == devno) {
	
	found = True ;
	break ;
	
      }
      
    }
    
    pstrcpy(name,mnt->mnt_dir) ;
    endmntent(fd) ;
    
    if ( ! found )
      return(False) ;
  }
  
  request.qf_magic = QF_MAGIC ;
  request.qf_entry.id = geteuid() ;
  
  if (quotactl(name, Q_GETQUOTA, &request) == -1)
    return(False) ;
  
  if ( ! request.user )
    return(False) ;
  
  if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
    
    if ( ! quota_default ) {
      
      if ( quotactl(name, Q_GETHEADER, &header) == -1 )
	return(False) ;
      else
	quota_default = header.user_h.def_fq ;
    }
    
    *dfree = quota_default ;
    
  }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
    
    *dfree = 0 ;
    
  }else{
    
    *dfree = request.qf_entry.user_q.f_quota ;
    
  }
  
  *dsize = request.qf_entry.user_q.f_use ;
  
  if ( *dfree < *dsize )
    *dfree = 0 ;
  else
    *dfree -= *dsize ;
  
  *bsize = 4096 ;  /* Cray blocksize */
  
  return(True) ;
  
}
Пример #11
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
	uid_t euser_id;
	int ret;
	struct dqblk D;
#if defined(SUNOS5)
	struct quotctl command;
	int file;
	static struct mnttab mnt;
	static pstring name;
	pstring devopt;
#else /* SunOS4 */
	struct mntent *mnt;
	static pstring name;
#endif
	FILE *fd;
	SMB_STRUCT_STAT sbuf;
	SMB_DEV_T devno ;
	static SMB_DEV_T devno_cached = 0 ;
	static int found ;

	euser_id = geteuid();
  
	if ( sys_stat(path,&sbuf) == -1 )
		return(False) ;
  
	devno = sbuf.st_dev ;
	DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno));
	if ( devno != devno_cached ) {
		devno_cached = devno ;
#if defined(SUNOS5)
		if ((fd = sys_fopen(MNTTAB, "r")) == NULL)
			return(False) ;
    
		found = False ;
		slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno);
		while (getmntent(fd, &mnt) == 0) {
			if( !hasmntopt(&mnt, devopt) )
				continue;

			DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt.mnt_mountp,devopt));

			/* quotas are only on vxfs, UFS or NFS */
			if ( strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 ||
				strcmp( mnt.mnt_fstype, "nfs" ) == 0    ||
				strcmp( mnt.mnt_fstype, "vxfs" ) == 0  ) { 
					found = True ;
					break;
			}
		}
    
		pstrcpy(name,mnt.mnt_mountp) ;
		pstrcat(name,"/quotas") ;
		fclose(fd) ;
#else /* SunOS4 */
		if ((fd = setmntent(MOUNTED, "r")) == NULL)
			return(False) ;
    
		found = False ;
		while ((mnt = getmntent(fd)) != NULL) {
			if ( sys_stat(mnt->mnt_dir,&sbuf) == -1 )
				continue ;
			DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n", mnt->mnt_dir,(unsigned int)sbuf.st_dev));
			if (sbuf.st_dev == devno) {
				found = True ;
				break;
			}
		}
    
		pstrcpy(name,mnt->mnt_fsname) ;
		endmntent(fd) ;
#endif
	}

	if ( ! found )
		return(False) ;

	save_re_uid();
	set_effective_uid(0);

#if defined(SUNOS5)
	if ( strcmp( mnt.mnt_fstype, "nfs" ) == 0) {
		BOOL retval;
		DEBUG(5,("disk_quotas: looking for mountpath (NFS) \"%s\"\n", mnt.mnt_special));
		retval = nfs_quotas(mnt.mnt_special, euser_id, bsize, dfree, dsize);
		restore_re_uid();
		return retval;
	}

	DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
	if((file=sys_open(name, O_RDONLY,0))<0) {
		restore_re_uid();
		return(False);
	}
	command.op = Q_GETQUOTA;
	command.uid = euser_id;
	command.addr = (caddr_t) &D;
	ret = ioctl(file, Q_QUOTACTL, &command);
	close(file);
#else
	DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name));
	ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
#endif

	restore_re_uid();

	if (ret < 0) {
		DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));

#if defined(SUNOS5) && defined(VXFS_QUOTA)
		/* If normal quotactl() fails, try vxfs private calls */
		set_effective_uid(euser_id);
		DEBUG(5,("disk_quotas: mount type \"%s\"\n", mnt.mnt_fstype));
		if ( 0 == strcmp ( mnt.mnt_fstype, "vxfs" )) {
			BOOL retval;
			retval = disk_quotas_vxfs(name, path, bsize, dfree, dsize);
			return(retval);
		}
#else
		return(False);
#endif
	}

	/* If softlimit is zero, set it equal to hardlimit.
	 */
  
	if (D.dqb_bsoftlimit==0)
		D.dqb_bsoftlimit = D.dqb_bhardlimit;

	/* Use softlimit to determine disk space. A user exceeding the quota is told
	 * that there's no space left. Writes might actually work for a bit if the
	 * hardlimit is set higher than softlimit. Effectively the disk becomes
	 * made of rubber latex and begins to expand to accommodate the user :-)
	 */

	if (D.dqb_bsoftlimit==0)
		return(False);
	*bsize = DEV_BSIZE;
	*dsize = D.dqb_bsoftlimit;

	if (D.dqb_curblocks > D.dqb_bsoftlimit) {
		*dfree = 0;
		*dsize = D.dqb_curblocks;
	} else
		*dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
      
	DEBUG(5,("disk_quotas for path \"%s\" returning  bsize %.0f, dfree %.0f, dsize %.0f\n",
		path,(double)*bsize,(double)*dfree,(double)*dsize));

	return(True);
}
Пример #12
0
BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
	int r;
	SMB_STRUCT_STAT S;
	FILE *fp;
	LINUX_SMB_DISK_QUOTA D;
	struct mntent *mnt;
	SMB_DEV_T devno;
	int found;
	uid_t euser_id;

	euser_id = geteuid();
  
	/* find the block device file */
  
	if ( sys_stat(path, &S) == -1 )
		return(False) ;

	devno = S.st_dev ;
  
	fp = setmntent(MOUNTED,"r");
	found = False ;
  
	while ((mnt = getmntent(fp))) {
		if ( sys_stat(mnt->mnt_dir,&S) == -1 )
			continue ;

		if (S.st_dev == devno) {
			found = True ;
			break;
		}
	}

	endmntent(fp) ;
  
	if (!found)
		return(False);

	save_re_uid();
	set_effective_uid(0);  

	if (strcmp(mnt->mnt_type, "xfs")) {
		r=get_smb_linux_gen_quota(mnt->mnt_fsname, euser_id, &D);
		if (r == -1) {
			r=get_smb_linux_v2_quota(mnt->mnt_fsname, euser_id, &D);
			if (r == -1)
				r=get_smb_linux_v1_quota(mnt->mnt_fsname, euser_id, &D);
		}
	} else {
		r=get_smb_linux_xfs_quota(mnt->mnt_fsname, euser_id, &D);
	}

	restore_re_uid();

	/* Use softlimit to determine disk space, except when it has been exceeded */
	*bsize = D.bsize;
	if (r == -1) {
		if (errno == EDQUOT) {
			*dfree =0;
			*dsize =D.curblocks;
			return (True);
		} else {
			return(False);
		}
	}

	/* Use softlimit to determine disk space, except when it has been exceeded */
	if (
		(D.softlimit && D.curblocks >= D.softlimit) ||
		(D.hardlimit && D.curblocks >= D.hardlimit) ||
		(D.isoftlimit && D.curinodes >= D.isoftlimit) ||
		(D.ihardlimit && D.curinodes>=D.ihardlimit)
	) {
		*dfree = 0;
		*dsize = D.curblocks;
	} else if (D.softlimit==0 && D.hardlimit==0) {
		return(False);
	} else {
		if (D.softlimit == 0)
			D.softlimit = D.hardlimit;
		*dfree = D.softlimit - D.curblocks;
		*dsize = D.softlimit;
	}

	return (True);
}
Пример #13
0
static bool below_threshold(struct statfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) {
#else
static bool below_threshold(struct statvfs buf, const char *prefix_type, const char *threshold_type, const double low_threshold) {
#endif
    if (strcasecmp(threshold_type, "percentage_free") == 0) {
        return 100.0 * (double)buf.f_bfree / (double)buf.f_blocks < low_threshold;
    } else if (strcasecmp(threshold_type, "percentage_avail") == 0) {
        return 100.0 * (double)buf.f_bavail / (double)buf.f_blocks < low_threshold;
    } else if (strcasecmp(threshold_type, "bytes_free") == 0) {
        return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold;
    } else if (strcasecmp(threshold_type, "bytes_avail") == 0) {
        return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold;
    } else if (threshold_type[0] != '\0' && strncasecmp(threshold_type + 1, "bytes_", strlen("bytes_")) == 0) {
        uint64_t base = strcasecmp(prefix_type, "decimal") == 0 ? DECIMAL_BASE : BINARY_BASE;
        double factor = 1;

        switch (threshold_type[0]) {
            case 'T':
            case 't':
                factor *= base;
            case 'G':
            case 'g':
                factor *= base;
            case 'M':
            case 'm':
                factor *= base;
            case 'K':
            case 'k':
                factor *= base;
                break;
            default:
                return false;
        }

        if (strcasecmp(threshold_type + 1, "bytes_free") == 0) {
            return (double)buf.f_bsize * (double)buf.f_bfree < low_threshold * factor;
        } else if (strcasecmp(threshold_type + 1, "bytes_avail") == 0) {
            return (double)buf.f_bsize * (double)buf.f_bavail < low_threshold * factor;
        }
    }

    return false;
}

/*
 * Does a statvfs and prints either free, used or total amounts of bytes in a
 * human readable manner.
 *
 */
void print_disk_info(yajl_gen json_gen, char *buffer, const char *path, const char *format, const char *format_not_mounted, const char *prefix_type, const char *threshold_type, const double low_threshold) {
    const char *walk;
    char *outwalk = buffer;
    bool colorful_output = false;

    INSTANCE(path);

#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__APPLE__)
    struct statfs buf;

    if (statfs(path, &buf) == -1)
        return;
#else
    struct statvfs buf;

    if (statvfs(path, &buf) == -1) {
        /* If statvfs errors, e.g., due to the path not existing,
         * we use the format for a not mounted device. */
        format = format_not_mounted;
    } else if (format_not_mounted != NULL) {
        FILE *mntentfile = setmntent("/etc/mtab", "r");
        struct mntent *m;
        bool found = false;

        while ((m = getmntent(mntentfile)) != NULL) {
            if (strcmp(m->mnt_dir, path) == 0) {
                found = true;
                break;
            }
        }
        endmntent(mntentfile);

        if (!found) {
            format = format_not_mounted;
        }
    }
#endif

    if (low_threshold > 0 && below_threshold(buf, prefix_type, threshold_type, low_threshold)) {
        START_COLOR("color_bad");
        colorful_output = true;
    }

    for (walk = format; *walk != '\0'; walk++) {
        if (*walk != '%') {
            *(outwalk++) = *walk;
            continue;
        }

        if (BEGINS_WITH(walk + 1, "free")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bfree, prefix_type);
            walk += strlen("free");
        }

        if (BEGINS_WITH(walk + 1, "used")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * ((uint64_t)buf.f_blocks - (uint64_t)buf.f_bfree), prefix_type);
            walk += strlen("used");
        }

        if (BEGINS_WITH(walk + 1, "total")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_blocks, prefix_type);
            walk += strlen("total");
        }

        if (BEGINS_WITH(walk + 1, "avail")) {
            outwalk += print_bytes_human(outwalk, (uint64_t)buf.f_bsize * (uint64_t)buf.f_bavail, prefix_type);
            walk += strlen("avail");
        }

        if (BEGINS_WITH(walk + 1, "percentage_free")) {
            outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)buf.f_bfree / (double)buf.f_blocks, pct_mark);
            walk += strlen("percentage_free");
        }

        if (BEGINS_WITH(walk + 1, "percentage_used_of_avail")) {
            outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)(buf.f_blocks - buf.f_bavail) / (double)buf.f_blocks, pct_mark);
            walk += strlen("percentage_used_of_avail");
        }

        if (BEGINS_WITH(walk + 1, "percentage_used")) {
            outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)(buf.f_blocks - buf.f_bfree) / (double)buf.f_blocks, pct_mark);
            walk += strlen("percentage_used");
        }

        if (BEGINS_WITH(walk + 1, "percentage_avail")) {
            outwalk += sprintf(outwalk, "%.01f%s", 100.0 * (double)buf.f_bavail / (double)buf.f_blocks, pct_mark);
            walk += strlen("percentage_avail");
        }
    }

    if (colorful_output)
        END_COLOR;

    *outwalk = '\0';
    OUTPUT_FULL_TEXT(buffer);
}
Пример #14
0
static int remove_from_mtab(char * mountpoint)
{
	int rc;
	int num_matches;
	FILE * org_fd;
	FILE * new_fd;
	struct mntent * mount_entry;

	/* Do we need to check if it is a symlink to e.g. /proc/mounts
	in which case we probably do not want to update it? */

	/* Do we first need to check if it is writable? */ 

	atexit(unlock_mtab);
	if (lock_mtab()) {
		printf("Mount table locked\n");
		return -EACCES;
	}
	
	if(verboseflg)
		printf("attempting to remove from mtab\n");

	org_fd = setmntent(MOUNTED, "r");

	if(org_fd == NULL) {
		printf("Can not open %s\n",MOUNTED);
		unlock_mtab();
		return -EIO;
	}

	new_fd = setmntent(MOUNTED_TEMP,"w");
	if(new_fd == NULL) {
		printf("Can not open temp file %s", MOUNTED_TEMP);
		endmntent(org_fd);
		unlock_mtab();
		return -EIO;
	}

	/* BB fix so we only remove the last entry that matches BB */
	num_matches = 0;
	while((mount_entry = getmntent(org_fd)) != NULL) {
		if(strcmp(mount_entry->mnt_dir, mountpoint) == 0) {
			num_matches++;
		}
	}	
	if(verboseflg)
		printf("%d matching entries in mount table\n", num_matches);
		
	/* Is there a better way to seek back to the first entry in mtab? */
	endmntent(org_fd);
	org_fd = setmntent(MOUNTED, "r");

	if(org_fd == NULL) {
		printf("Can not open %s\n",MOUNTED);
		unlock_mtab();
		return -EIO;
	}
	
	while((mount_entry = getmntent(org_fd)) != NULL) {
		if(strcmp(mount_entry->mnt_dir, mountpoint) != 0) {
			addmntent(new_fd, mount_entry);
		} else {
			if(num_matches != 1) {
				addmntent(new_fd, mount_entry);
				num_matches--;
			} else if(verboseflg)
				printf("entry not copied (ie entry is removed)\n");
		}
	}

	if(verboseflg)
		printf("done updating tmp file\n");
	rc = fchmod (fileno (new_fd), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
	if(rc < 0) {
		printf("error %s changing mode of %s\n", strerror(errno),
			MOUNTED_TEMP);
	}
	endmntent(new_fd);

	rc = rename(MOUNTED_TEMP, MOUNTED);

	if(rc < 0) {
		printf("failure %s renaming %s to %s\n",strerror(errno),
			MOUNTED_TEMP, MOUNTED);
		unlock_mtab();
		return -EIO;
	}

	unlock_mtab();
	
	return rc;
}
Пример #15
0
int main(int argc, char ** argv)
{
	int c;
	int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */
	char * orgoptions = NULL;
	char * share_name = NULL;
	char * ipaddr = NULL;
	char * uuid = NULL;
	char * mountpoint = NULL;
	char * options = NULL;
	char * resolved_path = NULL;
	char * temp;
	int rc;
	int rsize = 0;
	int wsize = 0;
	int nomtab = 0;
	int uid = 0;
	int gid = 0;
	int optlen = 0;
	int orgoptlen = 0;
	size_t options_size = 0;
	int retry = 0; /* set when we have to retry mount with uppercase */
	struct stat statbuf;
	struct utsname sysinfo;
	struct mntent mountent;
	FILE * pmntfile;

	/* setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE); */

	if(argc && argv) {
		thisprogram = argv[0];
	} else {
		mount_cifs_usage();
		exit(1);
	}

	if(thisprogram == NULL)
		thisprogram = "mount.cifs";

	uname(&sysinfo);
	/* BB add workstation name and domain and pass down */

/* #ifdef _GNU_SOURCE
	printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname);
#endif */
	if(argc > 2) {
		share_name = argv[1];
		mountpoint = argv[2];
	}

	/* add sharename in opts string as unc= parm */

	while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsSU:vVwt:",
			 longopts, NULL)) != -1) {
		switch (c) {
/* No code to do the following  options yet */
/*	case 'l':
		list_with_volumelabel = 1;
		break;
	case 'L':
		volumelabel = optarg;
		break; */
/*	case 'a':	       
		++mount_all;
		break; */

		case '?':
		case 'h':	 /* help */
			mount_cifs_usage ();
			exit(1);
		case 'n':
		    ++nomtab;
		    break;
		case 'b':
#ifdef MS_BIND
			flags |= MS_BIND;
#else
			fprintf(stderr,
				"option 'b' (MS_BIND) not supported\n");
#endif
			break;
		case 'm':
#ifdef MS_MOVE		      
			flags |= MS_MOVE;
#else
			fprintf(stderr,
				"option 'm' (MS_MOVE) not supported\n");
#endif
			break;
		case 'o':
			orgoptions = strdup(optarg);
		    break;
		case 'r':  /* mount readonly */
			flags |= MS_RDONLY;
			break;
		case 'U':
			uuid = optarg;
			break;
		case 'v':
			++verboseflag;
			break;
		case 'V':	   
			printf ("mount.cifs version: %s.%s%s\n",
			MOUNT_CIFS_VERSION_MAJOR,
			MOUNT_CIFS_VERSION_MINOR,
			MOUNT_CIFS_VENDOR_SUFFIX);
			if(mountpassword) {
				memset(mountpassword,0,64);
			}
			exit (0);
		case 'w':
			flags &= ~MS_RDONLY;
			break;
		case 'R':
			rsize = atoi(optarg) ;
			break;
		case 'W':
			wsize = atoi(optarg);
			break;
		case '1':
			if (isdigit(*optarg)) {
				char *ep;

				uid = strtoul(optarg, &ep, 10);
				if (*ep) {
					printf("bad uid value \"%s\"\n", optarg);
					exit(1);
				}
			} else {
				struct passwd *pw;

				if (!(pw = getpwnam(optarg))) {
					printf("bad user name \"%s\"\n", optarg);
					exit(1);
				}
				uid = pw->pw_uid;
				endpwent();
			}
			break;
		case '2':
			if (isdigit(*optarg)) {
				char *ep;

				gid = strtoul(optarg, &ep, 10);
				if (*ep) {
					printf("bad gid value \"%s\"\n", optarg);
					exit(1);
				}
			} else {
				struct group *gr;

				if (!(gr = getgrnam(optarg))) {
					printf("bad user name \"%s\"\n", optarg);
					exit(1);
				}
				gid = gr->gr_gid;
				endpwent();
			}
			break;
		case 'u':
			got_user = 1;
			user_name = optarg;
			break;
		case 'd':
			domain_name = optarg; /* BB fix this - currently ignored */
			got_domain = 1;
			break;
		case 'p':
			if(mountpassword == NULL)
				mountpassword = (char *)calloc(65,1);
			if(mountpassword) {
				got_password = 1;
				strncpy(mountpassword,optarg,64);
			}
			break;
		case 'S':
			get_password_from_file(0 /* stdin */,NULL);
			break;
		case 't':
			break;
		default:
			printf("unknown mount option %c\n",c);
			mount_cifs_usage();
			exit(1);
		}
	}

	if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) {
		mount_cifs_usage();
		exit(1);
	}

	if (getenv("PASSWD")) {
		if(mountpassword == NULL)
			mountpassword = (char *)calloc(65,1);
		if(mountpassword) {
			strncpy(mountpassword,getenv("PASSWD"),64);
			got_password = 1;
		}
	} else if (getenv("PASSWD_FD")) {
		get_password_from_file(atoi(getenv("PASSWD_FD")),NULL);
	} else if (getenv("PASSWD_FILE")) {
		get_password_from_file(0, getenv("PASSWD_FILE"));
	}

        if (orgoptions && parse_options(&orgoptions, &flags)) {
                rc = -1;
		goto mount_exit;
	}
	ipaddr = parse_server(&share_name);
	if((ipaddr == NULL) && (got_ip == 0)) {
		printf("No ip address specified and hostname not found\n");
		rc = -1;
		goto mount_exit;
	}
	
	/* BB save off path and pop after mount returns? */
	resolved_path = (char *)malloc(PATH_MAX+1);
	if(resolved_path) {
		/* Note that if we can not canonicalize the name, we get
		another chance to see if it is valid when we chdir to it */
		if (realpath(mountpoint, resolved_path)) {
			mountpoint = resolved_path; 
		}
	}
	if(chdir(mountpoint)) {
		printf("mount error: can not change directory into mount target %s\n",mountpoint);
		rc = -1;
		goto mount_exit;
	}

	if(stat (".", &statbuf)) {
		printf("mount error: mount point %s does not exist\n",mountpoint);
		rc = -1;
		goto mount_exit;
	}

	if (S_ISDIR(statbuf.st_mode) == 0) {
		printf("mount error: mount point %s is not a directory\n",mountpoint);
		rc = -1;
		goto mount_exit;
	}

	if((getuid() != 0) && (geteuid() == 0)) {
		if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) {
#ifndef CIFS_ALLOW_USR_SUID
			/* Do not allow user mounts to control suid flag
			for mount unless explicitly built that way */
			flags |= MS_NOSUID | MS_NODEV;
#endif						
		} else {
			printf("mount error: permission denied or not superuser and mount.cifs not installed SUID\n"); 
			return -1;
		}
	}

	if(got_user == 0) {
		user_name = getusername();
		got_user = 1;
	}
       
	if(got_password == 0) {
		char *tmp_pass;
		tmp_pass = getpass("Password: "******"Password not entered, exiting.\n");
			return -1;
		}
		strncpy(mountpassword, tmp_pass, 64);
						 
		got_password = 1;
	}
	/* FIXME launch daemon (handles dfs name resolution and credential change) 
	   remember to clear parms and overwrite password field before launching */
mount_retry:
	if(orgoptions) {
		optlen = strlen(orgoptions);
		orgoptlen = optlen;
	} else
		optlen = 0;
	if(share_name)
		optlen += strlen(share_name) + 4;
	else {
		printf("No server share name specified\n");
		printf("\nMounting the DFS root for server not implemented yet\n");
                exit(1);
	}
	if(user_name)
		optlen += strlen(user_name) + 6;
	if(ipaddr)
		optlen += strlen(ipaddr) + 4;
	if(mountpassword)
		optlen += strlen(mountpassword) + 6;
	if(options) {
		free(options);
		options = NULL;
	}
	options_size = optlen + 10 + 64;
	options = (char *)malloc(options_size /* space for commas in password */ + 8 /* space for domain=  , domain name itself was counted as part of the length username string above */);

	if(options == NULL) {
		printf("Could not allocate memory for mount options\n");
		return -1;
	}

	options[0] = 0;
	strlcpy(options,"unc=",options_size);
	strlcat(options,share_name,options_size);
	/* scan backwards and reverse direction of slash */
	temp = strrchr(options, '/');
	if(temp > options + 6)
		*temp = '\\';
	if(ipaddr) {
		strlcat(options,",ip=",options_size);
		strlcat(options,ipaddr,options_size);
	}

	if(user_name) {
		/* check for syntax like user=domain\user */
		if(got_domain == 0)
			domain_name = check_for_domain(&user_name);
		strlcat(options,",user="******",domain=",options_size);
			strlcat(options,domain_name,options_size);
		}
	}
	if(mountpassword) {
		/* Commas have to be doubled, or else they will
		look like the parameter separator */
/*		if(sep is not set)*/
		if(retry == 0)
			check_for_comma(&mountpassword);
		strlcat(options,",pass="******",ver=",options_size);
	strlcat(options,MOUNT_CIFS_VERSION_MAJOR,options_size);

	if(orgoptions) {
		strlcat(options,",",options_size);
		strlcat(options,orgoptions,options_size);
	}
	if(prefixpath) {
		strlcat(options,",prefixpath=",options_size);
		strlcat(options,prefixpath,options_size); /* no need to cat the / */
	}
	if(verboseflag)
		printf("\nmount.cifs kernel mount options %s \n",options);
	if(mount(share_name, mountpoint, "cifs", flags, options)) {
	/* remember to kill daemon on error */
		char * tmp;

		switch (errno) {
		case 0:
			printf("mount failed but no error number set\n");
			break;
		case ENODEV:
			printf("mount error: cifs filesystem not supported by the system\n");
			break;
		case ENXIO:
			if(retry == 0) {
				retry = 1;
				tmp = share_name;
				while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) {
					*tmp = toupper((unsigned char)*tmp);
		        		tmp++;
				}
				if(!*tmp) {
					printf("retrying with upper case share name\n");
					goto mount_retry;
				}
			}
		default:
			printf("mount error %d = %s\n",errno,strerror(errno));
		}
		printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n");
		rc = -1;
		goto mount_exit;
	} else {
		pmntfile = setmntent(MOUNTED, "a+");
		if(pmntfile) {
			mountent.mnt_fsname = share_name;
			mountent.mnt_dir = mountpoint; 
			mountent.mnt_type = CONST_DISCARD(char *,"cifs"); 
			mountent.mnt_opts = (char *)malloc(220);
			if(mountent.mnt_opts) {
				char * mount_user = getusername();
				memset(mountent.mnt_opts,0,200);
				if(flags & MS_RDONLY)
					strlcat(mountent.mnt_opts,"ro",220);
				else
					strlcat(mountent.mnt_opts,"rw",220);
				if(flags & MS_MANDLOCK)
					strlcat(mountent.mnt_opts,",mand",220);
				if(flags & MS_NOEXEC)
					strlcat(mountent.mnt_opts,",noexec",220);
				if(flags & MS_NOSUID)
					strlcat(mountent.mnt_opts,",nosuid",220);
				if(flags & MS_NODEV)
					strlcat(mountent.mnt_opts,",nodev",220);
				if(flags & MS_SYNCHRONOUS)
					strlcat(mountent.mnt_opts,",synch",220);
				if(mount_user) {
					if(getuid() != 0) {
						strlcat(mountent.mnt_opts,",user="******"could not update mount table\n");
		}
	}
Пример #16
0
/*
 * Check whether the file specified in "fusermount -u" is really a
 * mountpoint and not a symlink.  This is necessary otherwise the user
 * could move the mountpoint away and replace it with a symlink
 * pointing to an arbitrary mount, thereby tricking fusermount into
 * unmounting that (umount(2) will follow symlinks).
 *
 * This is the child process running in a separate mount namespace, so
 * we don't mess with the global namespace and if the process is
 * killed for any reason, mounts are automatically cleaned up.
 *
 * First make sure nothing is propagated back into the parent
 * namespace by marking all mounts "private".
 *
 * Then bind mount parent onto a stable base where the user can't move
 * it around.
 *
 * Finally check /proc/mounts for an entry matching the requested
 * mountpoint.  If it's found then we are OK, and the user can't move
 * it around within the parent directory as rename() will return
 * EBUSY.  Be careful to ignore any mounts that existed before the
 * bind.
 */
static int check_is_mount_child(void *p)
{
	const char **a = p;
	const char *last = a[0];
	const char *mnt = a[1];
	int res;
	const char *procmounts = "/proc/mounts";
	int found;
	FILE *fp;
	struct mntent *entp;
	int count;

	res = mount("", "/", "", MS_PRIVATE | MS_REC, NULL);
	if (res == -1) {
		fprintf(stderr, "%s: failed to mark mounts private: %s\n",
			progname, strerror(errno));
		return 1;
	}

	fp = setmntent(procmounts, "r");
	if (fp == NULL) {
		fprintf(stderr, "%s: failed to open %s: %s\n", progname,
			procmounts, strerror(errno));
		return 1;
	}

	count = 0;
	while ((entp = getmntent(fp)) != NULL)
		count++;
	endmntent(fp);

	fp = setmntent(procmounts, "r");
	if (fp == NULL) {
		fprintf(stderr, "%s: failed to open %s: %s\n", progname,
			procmounts, strerror(errno));
		return 1;
	}

	res = mount(".", "/", "", MS_BIND | MS_REC, NULL);
	if (res == -1) {
		fprintf(stderr, "%s: failed to bind parent to /: %s\n",
			progname, strerror(errno));
		return 1;
	}

	found = 0;
	while ((entp = getmntent(fp)) != NULL) {
		if (count > 0) {
			count--;
			continue;
		}
		if (entp->mnt_dir[0] == '/' &&
		    strcmp(entp->mnt_dir + 1, last) == 0) {
			found = 1;
			break;
		}
	}
	endmntent(fp);

	if (!found) {
		fprintf(stderr, "%s: %s not mounted\n", progname, mnt);
		return 1;
	}

	return 0;
}
Пример #17
0
void
sensorMonitor_adv_common_fillSensorTopic
(
    xme_core_component_config_t* const componentConfig
)
{
    sensorMonitor_adv_sensorB_sensorBComponent_config_t* config = (sensorMonitor_adv_sensorB_sensorBComponent_config_t*) componentConfig;

#ifndef WIN32
    // Linux implementation

    int driveCount = 0;
    int selectedDrive = 0;
    FILE* fp;
    struct mntent *ent;

    fp = setmntent("/etc/mtab", "r");
    while ((ent = getmntent(fp)) != NULL)
    {
        if (strcmp(ent->mnt_fsname, "none") == 0 || strcmp(ent->mnt_fsname, "sysfs") == 0 || strcmp(ent->mnt_fsname, "proc") == 0 ||
            strcmp(ent->mnt_fsname, "gvfs-fuse-daemon") == 0 || strcmp(ent->mnt_fsname, "devpts") == 0)
        {
            // Ignore this partition
            continue;
        }

        // List this partition
        XME_LOG(XME_LOG_ALWAYS, "[%d] %s %s\n", driveCount++, ent->mnt_dir, ent->mnt_type);
    }
    endmntent(fp);

    do
    {
        XME_LOG(XME_LOG_ALWAYS, "Which partition do you wish to monitor? [0-%d]: ", driveCount-1);
        if (!scanf("%d", &selectedDrive))
        {
            selectedDrive = -1;
        }
    }
    while (selectedDrive < 0 || selectedDrive> driveCount-1);

    driveCount = 0;
    fp = setmntent("/etc/mtab", "r");
    while ((ent = getmntent(fp)) != NULL)
    {
        if (strcmp(ent->mnt_fsname, "none") == 0 || strcmp(ent->mnt_fsname, "sysfs") == 0 || strcmp(ent->mnt_fsname, "proc") == 0 ||
            strcmp(ent->mnt_fsname, "gvfs-fuse-daemon") == 0 || strcmp(ent->mnt_fsname, "devpts") == 0)
        {
            // Ignore this partition
            continue;
        }

        // Check for matching drive
        if (driveCount++ == selectedDrive)
        {
            xme_hal_safeString_strncpy(config->sensorInstance, ent->mnt_dir, sizeof(config->sensorInstance));
            break;
        }
    }
    endmntent(fp);

#else // #ifndef WIN32
    // Windows implementation

    char szBuffer[1024];
    int driveCount = 0;
    int selectedDrive = 0;
    unsigned int i;
    DWORD length;

    length = GetLogicalDriveStrings(1024, (LPTSTR)szBuffer);
    XME_CHECK_MSG(0 != length, XME_CHECK_RVAL_VOID, XME_LOG_ERROR, "GetLogicalDriveStrings() failed: %d\n", GetLastError());

    XME_LOG(XME_LOG_ALWAYS, "The logical drives of this machine are:\n");
    for (i = 0U; i < length;)
    {
        if (szBuffer[i] != 0)
        {
            UINT type = GetDriveType((LPCSTR)(&szBuffer[i]));
            if (DRIVE_REMOVABLE != type && DRIVE_FIXED != type && DRIVE_RAMDISK != type)
            {
                // Ignore this drive
                i += strlen(&szBuffer[i]) + 1U;
                continue;
            }

            // List this drive
            XME_LOG(XME_LOG_ALWAYS, "[%d] : %s\n", driveCount++, (LPTSTR)(&szBuffer[i]));
            i += strlen(&szBuffer[i]) + 1U;
        }

        if (0 == szBuffer[i+1])
        {
            i++;
        }
    }

    do
    {
        XME_LOG(XME_LOG_ALWAYS, "\nWhich drive do you wish to monitor? [0-%d]: ", driveCount-1);
        scanf_s("%d", &selectedDrive);
    }
    while (selectedDrive < 0 || selectedDrive > driveCount-1);
    XME_LOG(XME_LOG_ALWAYS, "\n");

    driveCount = 0;
    for (i = 0; i < length;)
    {
        if (szBuffer[i] != 0)
        {
            UINT type = GetDriveType((LPCSTR)(&szBuffer[i]));
            if (DRIVE_REMOVABLE != type && DRIVE_FIXED != type && DRIVE_RAMDISK != type)
            {
                // Ignore this drive
                i += strlen(&szBuffer[i]) + 1;
                continue;
            }

            // Check for matching drive
            if(driveCount++ == selectedDrive)
            {
                xme_hal_safeString_strncpy(config->sensorInstance, (LPTSTR)(&szBuffer[i]), sizeof(config->sensorInstance));
                break;
            }
            i += strlen(&szBuffer[i]) + 1;
        }

        if (0 == szBuffer[i+1])
        {
            i++;
        }
    }

#endif // #ifndef WIN32
}
Пример #18
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo info;
# ifdef HAVE_MNTENT_H
	FILE *mnt;
	struct mntent *mntent;
	char	path[1024];
	char	*s;
	struct stat stbuf;

	mnt = setmntent ("/etc/fstab", "r");
	if (mnt) {
		while ((mntent = getmntent (mnt))) {
			/* detect floppies so we don't access them with the stat() below */
			GP_LOG_D ("found fstab fsname %s", mntent->mnt_fsname);

			if ((NULL != strstr(mntent->mnt_fsname,"fd"))	||
			    (NULL != strstr(mntent->mnt_fsname,"floppy")) ||
			    (NULL != strstr(mntent->mnt_fsname,"fuse"))	||
			    (NULL != strstr(mntent->mnt_fsname,"nfs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"cifs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"smbfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"afs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"autofs"))||
                            (NULL != strstr(mntent->mnt_fsname,"cgroup"))||
                            (NULL != strstr(mntent->mnt_fsname,"systemd"))||
                            (NULL != strstr(mntent->mnt_fsname,"mqueue"))||
                            (NULL != strstr(mntent->mnt_fsname,"securityfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"proc"))||
                            (NULL != strstr(mntent->mnt_fsname,"devtmpfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"devpts"))||
                            (NULL != strstr(mntent->mnt_fsname,"sysfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"gphotofs")||
			/* fstype based */
			    (NULL != strstr(mntent->mnt_type,"autofs"))	||
			    (NULL != strstr(mntent->mnt_type,"nfs"))	||
			    (NULL != strstr(mntent->mnt_type,"smbfs"))||
			    (NULL != strstr(mntent->mnt_type,"proc"))||
			    (NULL != strstr(mntent->mnt_type,"sysfs"))||
			    (NULL != strstr(mntent->mnt_type,"fuse"))||
			    (NULL != strstr(mntent->mnt_type,"cifs"))||
			    (NULL != strstr(mntent->mnt_type,"afs")) ||
			/* mount options */
				/* x-systemd.automount or similar */
			    (NULL != strstr(mntent->mnt_opts,"automount"))
)
			) {
				continue;
			}
			snprintf (path, sizeof(path), "%s/DCIM", mntent->mnt_dir);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mntent->mnt_dir);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			s = malloc (strlen(_("Media '%s'"))+strlen(mntent->mnt_fsname)+1);
			sprintf (s, _("Media '%s'"), mntent->mnt_fsname);
			gp_port_info_new (&info);
			gp_port_info_set_type (info, GP_PORT_DISK);
			gp_port_info_set_name (info, s);
			free (s);
			
			s = malloc (strlen("disk:")+strlen(mntent->mnt_dir)+1);
			sprintf (s, "disk:%s", mntent->mnt_dir);
			gp_port_info_set_path (info, s);
			if (gp_port_info_list_lookup_path (list, s) >= GP_OK) {
				free (s);
				continue;
			}
			free(s);
			CHECK (gp_port_info_list_append (list, info));
		}
		endmntent(mnt);
	}
	mnt = setmntent ("/etc/mtab", "r");
	if (mnt) {
		while ((mntent = getmntent (mnt))) {
			/* detect floppies so we don't access them with the stat() below */
			GP_LOG_D ("found mtab fsname %s", mntent->mnt_fsname);

			if ((NULL != strstr(mntent->mnt_fsname,"fd"))	||
			    (NULL != strstr(mntent->mnt_fsname,"floppy")) ||
			    (NULL != strstr(mntent->mnt_fsname,"fuse"))	||
			    (NULL != strstr(mntent->mnt_fsname,"nfs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"cifs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"smbfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"afs"))	||
			    (NULL != strstr(mntent->mnt_fsname,"autofs"))||
                            (NULL != strstr(mntent->mnt_fsname,"cgroup"))||
                            (NULL != strstr(mntent->mnt_fsname,"systemd"))||
                            (NULL != strstr(mntent->mnt_fsname,"mqueue"))||
                            (NULL != strstr(mntent->mnt_fsname,"securityfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"proc"))||
                            (NULL != strstr(mntent->mnt_fsname,"devtmpfs"))||
                            (NULL != strstr(mntent->mnt_fsname,"devpts"))||
                            (NULL != strstr(mntent->mnt_fsname,"sysfs"))||
			    (NULL != strstr(mntent->mnt_fsname,"gphotofs"))||
			/* fstype based */
			    (NULL != strstr(mntent->mnt_type,"autofs"))	||
			    (NULL != strstr(mntent->mnt_type,"nfs"))	||
			    (NULL != strstr(mntent->mnt_type,"smbfs"))||
			    (NULL != strstr(mntent->mnt_type,"proc"))||
			    (NULL != strstr(mntent->mnt_type,"sysfs"))||
			    (NULL != strstr(mntent->mnt_type,"fuse"))||
			    (NULL != strstr(mntent->mnt_type,"cifs"))||
			    (NULL != strstr(mntent->mnt_type,"afs")) ||
			/* options */
			    (NULL != strstr(mntent->mnt_opts,"automount"))
			) {
				continue;
			}

			snprintf (path, sizeof(path), "%s/DCIM", mntent->mnt_dir);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mntent->mnt_dir);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			/* automount should be blacklist here, but we still need
			 * to look it up first otherwise the automounted camera
			 * won't appear.
			 */
			if (NULL != strstr(mntent->mnt_fsname, "automount")) {
				continue;
			}
			gp_port_info_new (&info);
			gp_port_info_set_type (info, GP_PORT_DISK);
			s = malloc (strlen(_("Media '%s'"))+strlen(mntent->mnt_fsname)+1);
			sprintf (s, _("Media '%s'"),  mntent->mnt_fsname);
			gp_port_info_set_name (info, s);
			free (s);
			
			s = malloc (strlen("disk:")+strlen(mntent->mnt_dir)+1);
			sprintf (s, "disk:%s", mntent->mnt_dir);
			gp_port_info_set_path (info, s);
			if (gp_port_info_list_lookup_path (list, s) >= GP_OK) {
				free (s);
				continue;
			}
			free (s);
			CHECK (gp_port_info_list_append (list, info));
		}
		endmntent(mnt);
	}
# else
#  ifdef HAVE_MNTTAB
	FILE *mnt;
	struct mnttab mnttab;
	char	path[1024];
	struct stat stbuf;

	info.type = GP_PORT_DISK;

	mnt = fopen ("/etc/fstab", "r");
	if (mnt) {
		while (! getmntent (mnt, &mntent)) {
			/* detect floppies so we don't access them with the stat() below */
			if (	(NULL != strstr(mnttab.mnt_special,"fd")) ||
				(NULL != strstr(mnttab.mnt_special,"floppy"))
			)
				continue;

			snprintf (path, sizeof(path), "%s/DCIM", mnttab.mnt_mountp);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mnttab.mnt_mountp);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			snprintf (info.name, sizeof(info.name), _("Media '%s'"), mntent.mnt_special),
			snprintf (info.path, sizeof(info.path), "disk:%s", mntent.mnt_mountp);
			if (gp_port_info_list_lookup_path (list, info.path) >= GP_OK)
				continue;
			CHECK (gp_port_info_list_append (list, info));
		}
		fclose(mnt);
	}
	mnt = fopen ("/etc/mtab", "r");
	if (mnt) {
		while (! getmntent (mnt, &mntent)) {
			/* detect floppies so we don't access them with the stat() below */
			if (	(NULL != strstr(mnttab.mnt_special,"fd")) ||
				(NULL != strstr(mnttab.mnt_special,"floppy"))
			)
				continue;

			snprintf (path, sizeof(path), "%s/DCIM", mnttab.mnt_mountp);
			if (-1 == stat(path, &stbuf)) {
				snprintf (path, sizeof(path), "%s/dcim", mnttab.mnt_mountp);
				if (-1 == stat(path, &stbuf))
					continue;
			}
			snprintf (info.name, sizeof(info.name), _("Media '%s'"), mntent.mnt_special),
			snprintf (info.path, sizeof(info.path), "disk:%s", mntent.mnt_mountp);
			if (gp_port_info_list_lookup_path (list, info.path) >= GP_OK)
				continue;
			CHECK (gp_port_info_list_append (list, info));
		}
		fclose(mnt);
	}
#  endif
# endif

	/* generic disk:/xxx/ matcher */
	gp_port_info_new (&info);
	gp_port_info_set_type (info, GP_PORT_DISK);
	gp_port_info_set_name (info, "");
	gp_port_info_set_path (info, "^disk:");
	CHECK (gp_port_info_list_append (list, info));
	return GP_OK;
}
Пример #19
0
static int
HandleMTab(char *cacheMountDir)
{
#if (defined (AFS_HPUX_ENV) || defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV))
    FILE *tfilep;
#if defined(AFS_SGI_ENV) || defined(AFS_LINUX20_ENV)
    struct mntent tmntent;
    char *dir;
    int i;

    tfilep = setmntent("/etc/mtab", "a+");
    if (!tfilep) {
	printf("Can't open /etc/mtab for writing (errno %d); not adding "
	       "an entry for AFS\n", errno);
	return 1;
    }

    dir = strdup(cacheMountDir);

    /* trim trailing slashes; don't look at dir[0] in case we are somehow
     * just "/" */
    for (i = strlen(dir)-1; i > 0; i--) {
	if (dir[i] == '/') {
	    dir[i] = '\0';
	} else {
	    break;
	}
    }

    tmntent.mnt_fsname = "AFS";
    tmntent.mnt_dir = dir;
    tmntent.mnt_type = "afs";
    tmntent.mnt_opts = "rw";
    tmntent.mnt_freq = 1;
    tmntent.mnt_passno = 3;
    addmntent(tfilep, &tmntent);
    endmntent(tfilep);

    free(dir);
    dir = NULL;
#else
    struct mntent tmntent;

    memset(&tmntent, '\0', sizeof(struct mntent));
    tfilep = setmntent(MOUNTED_TABLE, "a+");
    if (!tfilep) {
	printf("Can't open %s for write; Not adding afs entry to it\n",
	       MOUNTED_TABLE);
	return 1;
    }
    tmntent.mnt_fsname = "AFS";
    tmntent.mnt_dir = cacheMountDir;
    tmntent.mnt_type = "xx";
    tmntent.mnt_opts = "rw";
    tmntent.mnt_freq = 1;
    tmntent.mnt_passno = 3;
#ifdef	AFS_HPUX_ENV
    tmntent.mnt_type = "afs";
    tmntent.mnt_time = time(0);
    tmntent.mnt_cnode = 0;
#endif
    addmntent(tfilep, &tmntent);
    endmntent(tfilep);
#endif /* AFS_SGI_ENV */
#endif /* unreasonable systems */
#ifdef AFS_DARWIN_ENV
#ifndef AFS_DARWIN100_ENV
    mach_port_t diskarb_port;
    kern_return_t status;

    status = DiskArbStart(&diskarb_port);
    if (status == KERN_SUCCESS) {
	status =
	    DiskArbDiskAppearedWithMountpointPing_auto("AFS",
						       DISK_ARB_NETWORK_DISK_FLAG,
						       cacheMountDir);
    }

    return status;
#endif
#endif /* AFS_DARWIN_ENV */
    return 0;
}
int main(int argc, char **argv)
{
#ifdef HAVE_FHANDLE_SYSCALLS
	char *filename, *file, *mount_point = NULL, *readbuf = NULL;
	int ret, rc = -EINVAL, mnt_id, mnt_fd, fd1, fd2, i, len, offset;
	struct file_handle *fh = NULL;
	int file_size, mtime, ctime;
	struct lu_fid *parent, *fid;
	struct mntent *ent;
	struct stat st;
	__ino_t inode;
	FILE *mntpt;

	if (argc != 2)
		usage(argv[0]);

	file = argv[1];
	if (file[0] != '/') {
		fprintf(stderr, "Need the absolete path of the file\n");
		goto out;
	}

	fd1 = open(file, O_RDONLY);
	if (fd1 < 0) {
		fprintf(stderr, "open file %s error: %s\n",
			file, strerror(errno));
		rc = errno;
		goto out;
	}

	/* Get file stats using fd1 from traditional open */
	bzero(&st, sizeof(struct stat));
	rc = fstat(fd1, &st);
	if (rc < 0) {
		fprintf(stderr, "fstat(%s) error: %s\n", file,
			strerror(errno));
		rc = errno;
		goto out_fd1;
	}

	inode = st.st_ino;
	mtime = st.st_mtime;
	ctime = st.st_ctime;
	file_size = st.st_size;

	/* Now for the setup to use fhandles */
	mntpt = setmntent("/etc/mtab", "r");
	if (mntpt == NULL) {
		fprintf(stderr, "setmntent error: %s\n",
			strerror(errno));
		rc = errno;
		goto out_fd1;
	}

	while (NULL != (ent = getmntent(mntpt))) {
		if ((strncmp(file, ent->mnt_dir, strlen(ent->mnt_dir)) == 0) &&
		    (strcmp(ent->mnt_type, "lustre") == 0)) {
			mount_point = ent->mnt_dir;
			break;
		}
	}
	endmntent(mntpt);

	if (mount_point == NULL) {
		fprintf(stderr, "file is not located on a lustre file "
			"system?\n");
		goto out_fd1;
	}

	filename = rindex(file, '/') + 1;

	/* Open mount point directory */
	mnt_fd = open(mount_point, O_DIRECTORY);
	if (mnt_fd < 0) {
		fprintf(stderr, "open(%s) error: %s\n)", mount_point,
			strerror(errno));
		rc = errno;
		goto out_fd1;
	}

	/* Allocate memory for file handle */
	fh = malloc(sizeof(struct file_handle) + MAX_HANDLE_SZ);
	if (!fh) {
		fprintf(stderr, "malloc(%d) error: %s\n", MAX_HANDLE_SZ,
			strerror(errno));
		rc = errno;
		goto out_mnt_fd;
	}
	fh->handle_bytes = MAX_HANDLE_SZ;

	/* Convert name to handle */
	ret = name_to_handle_at(mnt_fd, filename, fh, &mnt_id,
				AT_SYMLINK_FOLLOW);
	if (ret) {
		fprintf(stderr, "name_by_handle_at(%s) error: %s\n", filename,
			strerror(errno));
		rc = errno;
		goto out_f_handle;
	}

	/* Print out the contents of the file handle */
	fprintf(stdout, "fh_bytes: %u\nfh_type: %d\nfh_data: ",
		fh->handle_bytes, fh->handle_type);
	for (i = 0; i < fh->handle_bytes; i++)
		fprintf(stdout, "%02x ", fh->f_handle[i]);
	fprintf(stdout, "\n");

	/* Lustre stores both the parents FID and the file FID
	 * in the f_handle. */
	parent = (struct lu_fid *)(fh->f_handle + 16);
	fid = (struct lu_fid *)fh->f_handle;
	fprintf(stdout, "file's parent FID is "DFID"\n", PFID(parent));
	fprintf(stdout, "file FID is "DFID"\n", PFID(fid));

	/* Open the file handle */
	fd2 = open_by_handle_at(mnt_fd, fh, O_RDONLY);
	if (fd2 < 0) {
		fprintf(stderr, "open_by_handle_at(%s) error: %s\n", filename,
			strerror(errno));
		rc = errno;
		goto out_f_handle;
	}

	/* Get file size */
	bzero(&st, sizeof(struct stat));
	rc = fstat(fd2, &st);
	if (rc < 0) {
		fprintf(stderr, "fstat(%s) error: %s\n", filename,
			strerror(errno));
		rc = errno;
		goto out_fd2;
	}

	if (ctime != st.st_ctime || file_size != st.st_size ||
	    inode != st.st_ino || mtime != st.st_mtime) {
		fprintf(stderr, "stat data does not match between fopen "
			"and fhandle case\n");
		goto out_fd2;
	}

	if (st.st_size) {
		len = st.st_blksize;
		readbuf = malloc(len);
		if (readbuf == NULL) {
			fprintf(stderr, "malloc(%d) error: %s\n", len,
				strerror(errno));
			rc = errno;
			goto out_fd2;
		}

		for (offset = 0; offset < st.st_size; offset += len) {
			/* read from the file */
			rc = read(fd2, readbuf, len);
			if (rc < 0) {
				fprintf(stderr, "read(%s) error: %s\n",
					filename, strerror(errno));
				rc = errno;
				goto out_readbuf;
			}
		}
	}

	rc = 0;
	fprintf(stdout, "check_fhandle_syscalls test Passed!\n");

out_readbuf:
	if (readbuf != NULL)
		free(readbuf);
out_fd2:
	close(fd2);
out_f_handle:
	free(fh);
out_mnt_fd:
	close(mnt_fd);
out_fd1:
	close(fd1);
out:
	return rc;
#else /* !HAVE_FHANDLE_SYSCALLS */
	if (argc != 2)
		usage(argv[0]);

	fprintf(stderr, "HAVE_FHANDLE_SYSCALLS not defined\n");
	return 0;
#endif /* HAVE_FHANDLE_SYSCALLS */
}
Пример #21
0
void CDBoxInfoWidget::paint()
{
	const int headSize = 5;
	const char *head[headSize] = {"Filesystem", "Size", "Used", "Available", "Use%"};
	int fontWidth = g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->getWidth();
	int sizeOffset = fontWidth * 7;//9999.99M
	int percOffset = fontWidth * 3 ;//100%
	int nameOffset = fontWidth * 9;//WWWwwwwwww
	int offsetw = nameOffset+ (sizeOffset+10)*3 +10+percOffset+10;
	offsetw += 20;
	width = offsetw + 10 + 120;
	height = hheight + 6 * mheight;

	struct statfs s;
	FILE *          mountFile;
	struct mntent * mnt;

	/* this is lame, as it duplicates code. OTOH, it is small and fast enough...
	   The algorithm is exactly the same as below in the display routine */
	if ((mountFile = setmntent("/proc/mounts", "r")) == NULL) {
		perror("/proc/mounts");
	} else {
		while ((mnt = getmntent(mountFile)) != NULL) {
			if (::statfs(mnt->mnt_dir, &s) == 0) {
				switch (s.f_type)	/* f_type is long */
				{
				case 0xEF53L:		/*EXT2 & EXT3*/
				case 0x6969L:		/*NFS*/
				case 0xFF534D42L:	/*CIFS*/
				case 0x517BL:		/*SMB*/
				case 0x52654973L:	/*REISERFS*/
				case 0x65735546L:	/*fuse for ntfs*/
				case 0x58465342L:	/*xfs*/
				case 0x4d44L:		/*msdos*/
					break;
				case 0x72b6L:		/*jffs2*/
					if (strcmp(mnt->mnt_fsname, "rootfs") == 0)
						continue;
					height += mheight;
					break;
				default:
					continue;
				}
				height += mheight;
			}
		}
		endmntent(mountFile);
	}

	width = w_max(width, 0);
	height = h_max(height, 0);
	x = getScreenStartX(width);
	y = getScreenStartY(height);

	fprintf(stderr, "CDBoxInfoWidget::CDBoxInfoWidget() x = %d, y = %d, width = %d height = %d\n", x, y, width, height);
	int ypos=y;
	int i = 0;
	frameBuffer->paintBoxRel(x, ypos, width, hheight, COL_MENUHEAD_PLUS_0, RADIUS_LARGE, CORNER_TOP);
	frameBuffer->paintBoxRel(x, ypos+ hheight, width, height- hheight, COL_MENUCONTENT_PLUS_0, RADIUS_LARGE, CORNER_BOTTOM);

	ypos+= hheight + (mheight >>1);
	FILE* fd = fopen("/proc/cpuinfo", "rt");
	if (fd==NULL) {
		printf("error while opening proc-cpuinfo\n" );
	} else {
		char *buffer=NULL;
		size_t len = 0;
		ssize_t read;
		while ((read = getline(&buffer, &len, fd)) != -1) {
			if (!(strncmp(const_cast<char *>("Hardware"),buffer,8))) {
				char *t=rindex(buffer,'\n');
				if (t)
					*t='\0';

				std::string hw;
				char *p=rindex(buffer,':');
				if (p)
					hw=++p;
				hw+=" Info";
				g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->RenderString(x+10, y + hheight+1, width - 10, hw.c_str(), COL_MENUHEAD, 0, true); // UTF-8
				break;
			}
			i++;
			if (i > 2)
				continue;
			g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, buffer, COL_MENUCONTENT);
			ypos+= mheight;
		}
		fclose(fd);
		if (buffer)
			free(buffer);
	}
	char *ubuf=NULL, *sbuf=NULL;
	int buf_size=256;
	ubuf = new char[buf_size];
	sbuf = new char[buf_size];

	if (sbuf != NULL && ubuf != NULL) {
		int updays, uphours, upminutes;
		struct sysinfo info;
		struct tm *current_time;
		time_t current_secs;
		memset(sbuf, 0, 256);
		time(&current_secs);
		current_time = localtime(&current_secs);

		sysinfo(&info);

		snprintf( ubuf,buf_size, "%2d:%02d%s  up ",
			  current_time->tm_hour%12 ? current_time->tm_hour%12 : 12,
			  current_time->tm_min, current_time->tm_hour > 11 ? "pm" : "am");
		strcat(sbuf, ubuf);
		updays = (int) info.uptime / (60*60*24);
		if (updays) {
			snprintf(ubuf,buf_size, "%d day%s, ", updays, (updays != 1) ? "s" : "");
			strcat(sbuf, ubuf);
		}
		upminutes = (int) info.uptime / 60;
		uphours = (upminutes / 60) % 24;
		upminutes %= 60;
		if (uphours)
			snprintf(ubuf,buf_size,"%2d:%02d, ", uphours, upminutes);
		else
			snprintf(ubuf,buf_size,"%d min, ", upminutes);
		strcat(sbuf, ubuf);

		snprintf(ubuf,buf_size, "load: %ld.%02ld, %ld.%02ld, %ld.%02ld\n",
			 LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]),
			 LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]),
			 LOAD_INT(info.loads[2]), LOAD_FRAC(info.loads[2]));
		strcat(sbuf, ubuf);
		ypos+= mheight/2;
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, sbuf, COL_MENUCONTENT);
		ypos+= mheight;

		snprintf(ubuf,buf_size, "memory total %dKb, free %dKb", (int) info.totalram/1024, (int) info.freeram/1024);
		ypos+= mheight/2;
		g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ 10, ypos+ mheight, width - 10, ubuf, COL_MENUCONTENT);
		ypos+= mheight;
		int headOffset=0;
		int mpOffset=0;
		bool rec_mp=false;
		if ((mountFile = setmntent("/proc/mounts", "r")) == 0 ) {
			perror("/proc/mounts");
		}
		else {
			float gb=0;
			char c=' ';
			while ((mnt = getmntent(mountFile)) != 0) {
				if (::statfs(mnt->mnt_dir, &s) == 0) {
					switch (s.f_type)
					{
					case (int) 0xEF53:      /*EXT2 & EXT3*/
					case (int) 0x6969:      /*NFS*/
					case (int) 0xFF534D42:  /*CIFS*/
					case (int) 0x517B:      /*SMB*/
					case (int) 0x52654973:  /*REISERFS*/
					case (int) 0x65735546:  /*fuse for ntfs*/
					case (int) 0x58465342:  /*xfs*/
					case (int) 0x4d44:      /*msdos*/
						gb = 1024.0*1024.0;
						c = 'G';
						break;
					case (int) 0x72b6:	/*jffs2*/
						if (strcmp(mnt->mnt_fsname, "rootfs") == 0)
							continue;
						// paint mount head
						for (int j = 0; j < headSize; j++) {
							switch (j)
							{
							case 0:
								headOffset = 10;
								break;
							case 1:
								headOffset = nameOffset + 20;
								break;
							case 2:
								headOffset = nameOffset + sizeOffset+10 +20;
								break;
							case 3:
								headOffset = nameOffset + (sizeOffset+10)*2+15;
								break;
							case 4:
								headOffset = nameOffset + (sizeOffset+10)*3+15;
								break;
							}
							g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x+ headOffset, ypos+ mheight, width - 10, head[j], COL_MENUCONTENTINACTIVE);
						}
						ypos+= mheight;

						gb = 1024.0;
						c = 'M';
						break;
					default:
						continue;
					}
					if ( s.f_blocks > 0 ) {
						long	blocks_used;
						long	blocks_percent_used;
						blocks_used = s.f_blocks - s.f_bfree;
						blocks_percent_used = (long)(blocks_used * 100.0 / (blocks_used + s.f_bavail) + 0.5);
						//paint mountpoints
						for (int j = 0; j < headSize; j++) {
							switch (j)
							{
							case 0: {
								if (s.f_type != 0x72b6)
								{
									char *p1=NULL, *p2=NULL;
									p1=strchr(g_settings.network_nfs_recordingdir+1,'/') ;
									p2=strchr(mnt->mnt_dir+1,'/') ;
									if (p2) {
										if (strstr(p1,p2)) {

											rec_mp = true;
										}
									}
									else {
										if (strstr(g_settings.network_nfs_recordingdir,mnt->mnt_dir)) {
											rec_mp = true;
										}
									}
								}
								mpOffset = 10;
								snprintf(ubuf,buf_size,"%-10.10s",basename(mnt->mnt_fsname));
							}
							break;
							case 1:
								mpOffset = nameOffset + 10;
								snprintf(ubuf,buf_size,"%7.2f%c", (s.f_blocks * (s.f_bsize / 1024.0)) / gb, c);
								break;
							case 2:
								mpOffset = nameOffset+ (sizeOffset+10)*1+10;
								snprintf(ubuf,buf_size,"%7.2f%c", ((s.f_blocks - s.f_bfree)  * (s.f_bsize / 1024.0)) / gb, c);
								break;
							case 3:
								mpOffset = nameOffset+ (sizeOffset+10)*2+10;
								snprintf(ubuf,buf_size,"%7.2f%c", s.f_bavail * (s.f_bsize / 1024.0) / gb, c);
								break;
							case 4:
								mpOffset = nameOffset+ (sizeOffset+10)*3+10;
								snprintf(ubuf,buf_size,"%4ld%c", blocks_percent_used,'%');
								break;
							}
							g_Font[SNeutrinoSettings::FONT_TYPE_MENU]->RenderString(x + mpOffset, ypos+ mheight, width - 10, ubuf, rec_mp ? COL_MENUHEAD+2:COL_MENUCONTENT);
							rec_mp = false;
						}
						int pbw = width - offsetw - 10;
//fprintf(stderr, "width: %d offsetw: %d pbw: %d\n", width, offsetw, pbw);
						if (pbw > 8) /* smaller progressbar is not useful ;) */
						{
							CProgressBar pb(true, -1, -1, 30, 100, 70, true);
							pb.paintProgressBarDefault(x+offsetw, ypos+3, pbw, mheight-10, blocks_percent_used, 100);
						}
						ypos+= mheight;
					}
					i++;
				}
				if (ypos > y + height - mheight)	/* the screen is not high enough */
					break;				/* todo: scrolling? */
			}
			endmntent(mountFile);
		}
	}
	if (sbuf)
		delete[] sbuf;
	if (ubuf)
		delete[] ubuf;

}
Пример #22
0
/*
 * Helper function which checks a file in /etc/mtab format to see if a
 * filesystem is mounted.  Returns an error if the file doesn't exist
 * or can't be opened.
 */
static errcode_t check_mntent_file(const char *mtab_file, const char *file,
				   int *mount_flags, char *mtpt, int mtlen)
{
	struct mntent	*mnt;
	struct stat	st_buf;
	errcode_t	retval = 0;
	dev_t		file_dev=0, file_rdev=0;
	ino_t		file_ino=0;
	FILE		*f;
	int		fd;

	*mount_flags = 0;
	if ((f = setmntent (mtab_file, "r")) == NULL)
		return errno;
	if (stat(file, &st_buf) == 0) {
		if (S_ISBLK(st_buf.st_mode)) {
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
			file_rdev = st_buf.st_rdev;
#endif  /* __GNU__ */
		} else {
			file_dev = st_buf.st_dev;
			file_ino = st_buf.st_ino;
		}
	}
	while ((mnt = getmntent (f)) != NULL) {
		if (strcmp(file, mnt->mnt_fsname) == 0)
			break;
		if (stat(mnt->mnt_fsname, &st_buf) == 0) {
			if (S_ISBLK(st_buf.st_mode)) {
#ifndef __GNU__
				if (file_rdev && (file_rdev == st_buf.st_rdev))
					break;
#endif  /* __GNU__ */
			} else {
				if (file_dev && ((file_dev == st_buf.st_dev) &&
						 (file_ino == st_buf.st_ino)))
					break;
			}
		}
	}

	if (mnt == 0) {
#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
		/*
		 * Do an extra check to see if this is the root device.  We
		 * can't trust /etc/mtab, and /proc/mounts will only list
		 * /dev/root for the root filesystem.  Argh.  Instead we
		 * check if the given device has the same major/minor number
		 * as the device that the root directory is on.
		 */
		if (file_rdev && stat("/", &st_buf) == 0) {
			if (st_buf.st_dev == file_rdev) {
				*mount_flags = EXT2_MF_MOUNTED;
				if (mtpt)
					strncpy(mtpt, "/", mtlen);
				goto is_root;
			}
		}
#endif  /* __GNU__ */
		goto errout;
	}
#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
	/* Validate the entry in case /etc/mtab is out of date */
	/*
	 * We need to be paranoid, because some broken distributions
	 * (read: Slackware) don't initialize /etc/mtab before checking
	 * all of the non-root filesystems on the disk.
	 */
	if (stat(mnt->mnt_dir, &st_buf) < 0) {
		retval = errno;
		if (retval == ENOENT) {
#ifdef DEBUG
			printf("Bogus entry in %s!  (%s does not exist)\n",
			       mtab_file, mnt->mnt_dir);
#endif /* DEBUG */
			retval = 0;
		}
		goto errout;
	}
	if (file_rdev && (st_buf.st_dev != file_rdev)) {
#ifdef DEBUG
		printf("Bogus entry in %s!  (%s not mounted on %s)\n",
		       mtab_file, file, mnt->mnt_dir);
#endif /* DEBUG */
		goto errout;
	}
#endif /* __GNU__ */
	*mount_flags = EXT2_MF_MOUNTED;

#ifdef MNTOPT_RO
	/* Check to see if the ro option is set */
	if (hasmntopt(mnt, MNTOPT_RO))
		*mount_flags |= EXT2_MF_READONLY;
#endif

	if (mtpt)
		strncpy(mtpt, mnt->mnt_dir, mtlen);
	/*
	 * Check to see if we're referring to the root filesystem.
	 * If so, do a manual check to see if we can open /etc/mtab
	 * read/write, since if the root is mounted read/only, the
	 * contents of /etc/mtab may not be accurate.
	 */
	if (LONE_CHAR(mnt->mnt_dir, '/')) {
is_root:
#define TEST_FILE "/.ismount-test-file"
		*mount_flags |= EXT2_MF_ISROOT;
		fd = open(TEST_FILE, O_RDWR|O_CREAT);
		if (fd < 0) {
			if (errno == EROFS)
				*mount_flags |= EXT2_MF_READONLY;
		} else
			close(fd);
		(void) unlink(TEST_FILE);
	}
	retval = 0;
errout:
	endmntent (f);
	return retval;
}
Пример #23
0
Errors Device_getDeviceInfo(DeviceInfo   *deviceInfo,
                            const String deviceName
                           )
{
  FileStat fileStat;
  int      handle;
  #if defined(HAVE_IOCTL) && defined(HAVE_BLKSSZGET)
    int      i;
  #endif
  #if defined(HAVE_IOCTL) && defined(HAVE_BLKGETSIZE)
    long     l;
  #endif
  FILE          *mtab;
  struct mntent mountEntry;
  char          buffer[4096];

  assert(deviceName != NULL);
  assert(deviceInfo != NULL);

  // initialize variables
  deviceInfo->type        = DEVICE_TYPE_UNKNOWN;
  deviceInfo->size        = -1LL;
  deviceInfo->blockSize   = 0L;
//  deviceInfo->freeBlocks  = 0LL;
//  deviceInfo->totalBlocks = 0LL;
  deviceInfo->mountedFlag = FALSE;

  // get device meta data
  if (LSTAT(String_cString(deviceName),&fileStat) == 0)
  {
    deviceInfo->timeLastAccess  = fileStat.st_atime;
    deviceInfo->timeModified    = fileStat.st_mtime;
    deviceInfo->timeLastChanged = fileStat.st_ctime;
    deviceInfo->userId          = fileStat.st_uid;
    deviceInfo->groupId         = fileStat.st_gid;
    deviceInfo->permission      = (DevicePermission)fileStat.st_mode;
    #ifdef HAVE_MAJOR
      deviceInfo->major         = major(fileStat.st_rdev);
    #else
      deviceInfo->major         = 0;
    #endif
    #ifdef HAVE_MINOR
      deviceInfo->minor         = minor(fileStat.st_rdev);
    #else
      deviceInfo->minor         = 0;
    #endif
    deviceInfo->id              = (uint64)fileStat.st_ino;

    if      (S_ISCHR(fileStat.st_mode)) deviceInfo->type = DEVICE_TYPE_CHARACTER;
    else if (S_ISBLK(fileStat.st_mode)) deviceInfo->type = DEVICE_TYPE_BLOCK;
  }

  if (deviceInfo->type == DEVICE_TYPE_BLOCK)
  {
    // try to get block size, total size
    handle = open(String_cString(deviceName),O_RDONLY);
    if (handle != -1)
    {
      #if defined(HAVE_IOCTL) && defined(HAVE_BLKSSZGET)
        if (ioctl(handle,BLKSSZGET, &i) == 0) deviceInfo->blockSize = (ulong)i;
      #endif
      #if defined(HAVE_IOCTL) && defined(HAVE_BLKGETSIZE)
        if (ioctl(handle,BLKGETSIZE,&l) == 0) deviceInfo->size      = (int64)l*512;
      #endif
      close(handle);
    }
  }

  // check if mounted
  mtab = setmntent("/etc/mtab","r");
  if (mtab != NULL)
  {
    while (getmntent_r(mtab,&mountEntry,buffer,sizeof(buffer)) != NULL)
    {
      if (String_equalsCString(deviceName,mountEntry.mnt_fsname))
      {
        deviceInfo->mountedFlag = TRUE;
        break;
      }
    }
    endmntent(mtab);
  }

  return ERROR_NONE;
}
Пример #24
0
/*
 * Write out a mount list
 */
void
rewrite_mtab(mntlist *mp, const char *mnttabname)
{
  FILE *mfp;
  int error = 0;

  /*
   * Concoct a temporary name in the same directory as the target mount
   * table so that rename() will work.
   */
  char tmpname[64];
  int retries;
  int tmpfd;
  char *cp;
  char mcp[128];

  xstrlcpy(mcp, mnttabname, sizeof(mcp));
  cp = strrchr(mcp, '/');
  if (cp) {
    memmove(tmpname, mcp, cp - mcp);
    tmpname[cp - mcp] = '\0';
  } else {
    plog(XLOG_WARNING, "No '/' in mtab (%s), using \".\" as tmp directory", mnttabname);
    tmpname[0] = '.';
    tmpname[1] = '\0';
  }
  xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname));
  retries = 0;
enfile1:
#ifdef HAVE_MKSTEMP
  tmpfd = mkstemp(tmpname);
  fchmod(tmpfd, 0644);
#else /* not HAVE_MKSTEMP */
  mktemp(tmpname);
  tmpfd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC, 0644);
#endif /* not HAVE_MKSTEMP */
  if (tmpfd < 0) {
    if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto enfile1;
    }
    plog(XLOG_ERROR, "%s: open: %m", tmpname);
    return;
  }
  if (close(tmpfd) < 0)
    plog(XLOG_ERROR, "Couldn't close tmp file descriptor: %m");

  retries = 0;
enfile2:
  mfp = setmntent(tmpname, "w");
  if (!mfp) {
    if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto enfile2;
    }
    plog(XLOG_ERROR, "setmntent(\"%s\", \"w\"): %m", tmpname);
    error = 1;
    goto out;
  }
  while (mp) {
    if (mp->mnt) {
      if (addmntent(mfp, mp->mnt)) {
	plog(XLOG_ERROR, "Can't write entry to %s", tmpname);
	error = 1;
	goto out;
      }
    }
    mp = mp->mnext;
  }

  /*
   * SunOS 4.1 manuals say that the return code from entmntent()
   * is always 1 and to treat as a void.  That means we need to
   * call fflush() to make sure the new mtab file got written.
   */
  if (fflush(mfp)) {
    plog(XLOG_ERROR, "flush new mtab file: %m");
    error = 1;
    goto out;
  }
  (void) endmntent(mfp);

  /*
   * Rename temporary mtab to real mtab
   */
  if (rename(tmpname, mnttabname) < 0) {
    plog(XLOG_ERROR, "rename %s to %s: %m", tmpname, mnttabname);
    error = 1;
    goto out;
  }
out:
  if (error)
    (void) unlink(tmpname);
}
Пример #25
0
int 
main(int argc, char *argv[])
{
        int fd;

        char* mount_point;

        struct mntent *mnt;
        FILE* mtab;
        FILE* new_mtab;

        progname = argv[0];

        if (argc != 2) {
                usage();
                exit(1);
        }

        if (geteuid() != 0) {
                fprintf(stderr, "%s must be installed suid root\n", progname);
                exit(1);
        }

        mount_point = canonicalize(argv[1]);

	if (mount_point == NULL)
	{
		exit(1);
	}

        if (umount_ok(mount_point) != 0) {
                exit(1);
        }

        if (umount(mount_point) != 0) {
                fprintf(stderr, "Could not umount %s: %s\n",
                        mount_point, strerror(errno));
                exit(1);
        }

#ifndef EMBED
        if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
        {
                fprintf(stderr, "Can't get "MOUNTED"~ lock file");
                return 1;
        }
        close(fd);
	
        if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
                fprintf(stderr, "Can't open " MOUNTED ": %s\n",
                        strerror(errno));
                return 1;
        }

#define MOUNTED_TMP MOUNTED".tmp"

        if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
                fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
                        strerror(errno));
                endmntent(mtab);
                return 1;
        }

        while ((mnt = getmntent(mtab)) != NULL) {
                if (strcmp(mnt->mnt_dir, mount_point) != 0) {
                        addmntent(new_mtab, mnt);
                }
        }

        endmntent(mtab);

        if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
                fprintf(stderr, "Error changing mode of %s: %s\n",
                        MOUNTED_TMP, strerror(errno));
                exit(1);
        }

        endmntent(new_mtab);

        if (rename(MOUNTED_TMP, MOUNTED) < 0) {
                fprintf(stderr, "Cannot rename %s to %s: %s\n",
                        MOUNTED, MOUNTED_TMP, strerror(errno));
                exit(1);
        }

        if (unlink(MOUNTED"~") == -1)
        {
                fprintf(stderr, "Can't remove "MOUNTED"~");
                return 1;
        }
#endif /* EMBED */

	return 0;
}	
Пример #26
0
static FILE *
open_locked_mtab(const char *mnttabname, char *mode, char *fs)
{
  FILE *mfp = NULL;

  /*
   * There is a possible race condition if two processes enter
   * this routine at the same time.  One will be blocked by the
   * exclusive lock below (or by the shared lock in setmntent)
   * and by the time the second process has the exclusive lock
   * it will be on the wrong underlying object.  To check for this
   * the mtab file is stat'ed before and after all the locking
   * sequence, and if it is a different file then we assume that
   * it may be the wrong file (only "may", since there is another
   * race between the initial stat and the setmntent).
   *
   * Simpler solutions to this problem are invited...
   */
  int racing = 2;
  int rc;
  int retries = 0;
  struct stat st_before, st_after;

  if (mnt_file) {
# ifdef DEBUG
    dlog("Forced close on %s in read_mtab", mnttabname);
# endif /* DEBUG */
    endmntent(mnt_file);
    mnt_file = NULL;
  }
again:
  if (mfp) {
    endmntent(mfp);
    mfp = NULL;
  }
  if (stat(mnttabname, &st_before) < 0) {
    plog(XLOG_ERROR, "%s: stat: %m", mnttabname);
    if (errno == ESTALE) {
      /* happens occasionally */
      sleep(1);
      goto again;
    }
    /*
     * If 'mnttabname' file does not exist give setmntent() a
     * chance to create it (depending on the mode).
     * Otherwise, bail out.
     */
    else if (errno != ENOENT) {
      return 0;
    }
  }

eacces:
  mfp = setmntent((char *)mnttabname, mode);
  if (!mfp) {
    /*
     * Since setmntent locks the descriptor, it
     * is possible it can fail... so retry if
     * needed.
     */
    if (errno == EACCES || errno == EAGAIN) {
# ifdef DEBUG
      dlog("Blocked, trying to obtain exclusive mtab lock");
# endif /* DEBUG */
      goto eacces;
    } else if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto eacces;
    }
    plog(XLOG_ERROR, "setmntent(\"%s\", \"%s\"): %m", mnttabname, mode);
    return 0;
  }
  /*
   * At this point we have an exclusive lock on the mount list,
   * but it may be the wrong one so...
   */

  /*
   * Need to get an exclusive lock on the current
   * mount table until we have a new copy written
   * out, when the lock is released in free_mntlist.
   * flock is good enough since the mount table is
   * not shared between machines.
   */
  do
    rc = lock(fileno(mfp));
  while (rc < 0 && errno == EINTR);
  if (rc < 0) {
    plog(XLOG_ERROR, "Couldn't lock %s: %m", mnttabname);
    endmntent(mfp);
    return 0;
  }
  /*
   * Now check whether the mtab file has changed under our feet
   */
  if (stat(mnttabname, &st_after) < 0) {
    plog(XLOG_ERROR, "%s: stat: %m", mnttabname);
    goto again;
  }
  if (st_before.st_dev != st_after.st_dev ||
      st_before.st_ino != st_after.st_ino) {
    struct timeval tv;
    if (racing == 0) {
      /* Sometimes print a warning */
      plog(XLOG_WARNING,
	   "Possible mount table race - retrying %s", fs);
    }
    racing = (racing + 1) & 3;
    /*
     * Take a nap.  From: Doug Kingston <*****@*****.**>
     */
    tv.tv_sec = 0;
    tv.tv_usec = (am_mypid & 0x07) << 17;
    if (tv.tv_usec)
      if (select(0, (voidp) 0, (voidp) 0, (voidp) 0, &tv) < 0)
	plog(XLOG_WARNING, "mtab nap failed: %m");

    goto again;
  }

  return mfp;
}
Пример #27
0
psi_mountlist_t *
psi_arch_mountlist(const int remote)
{
    FILE *mntent;
    struct mntent mnt;
    char buf[PATH_MAX * 3];     /* size used in autofs so I hope it's okay */
    psi_mountlist_t *ml = NULL;
    psi_mountinfo_t *mounti, **mounts;

    /* Open /etc/mtab */
    mntent = setmntent(_PATH_MOUNTED, "r");
    if (mntent == NULL)
        return (psi_mountlist_t *) PyErr_SetFromErrnoWithFilename(
            PyExc_OSError, _PATH_MOUNTED);

    /* Create our (empty) mountlist */
    ml = (psi_mountlist_t *)psi_calloc(sizeof(psi_mountlist_t));
    if (ml == NULL) {
        fclose(mntent);
        return NULL;
    }

    /* Step through each line in the mount file */
    while (getmntent_r(mntent, &mnt, buf, sizeof(buf)) != NULL) {

        /* Skip remote filesystems if not asked for them */
        if (!remote &&
            (strchr(mnt.mnt_fsname, ':') != NULL ||
             strncmp(mnt.mnt_fsname, "//", 2) == 0))
            continue;

        /* Allocate space for the mount information */
        if ((mounti = psi_calloc(sizeof(psi_mountinfo_t))) == NULL) {
            fclose(mntent);
            psi_free_mountlist(ml);
            return NULL;
        }
        
        /* And then allocate more space for the mount list */
        mounts = (psi_mountinfo_t **)psi_realloc(
            ml->mounts,
            (ml->count + 1) * sizeof(psi_mountinfo_t *));
        if (mounts == NULL) {
            fclose(mntent);
            psi_free_mountinfo(mounti);
            psi_free_mountlist(ml);
            return NULL;
        }
        ml->mounts = mounts;
        ml->mounts[ml->count] = mounti;
        ml->count += 1;

        /* Finally add the information to mounti */
        if (set_mntent(mounti, &mnt) < 0) {
            fclose(mntent);
            psi_free_mountlist(ml);
            return NULL;
        }
        if (posix_set_vfs(mounti) < 0) {
            fclose(mntent);
            psi_free_mountlist(ml);
            return NULL;
        }
    }
    if (!feof(mntent)) {        /* Uh oh, we had a read error */
        endmntent(mntent);
        psi_free_mountlist(ml);
        PyErr_Format(PyExc_OSError, "Read error in %s", _PATH_MOUNTED);
        return NULL;
    }
    endmntent(mntent);
    return ml;
}
Пример #28
0
static void CheckMounts(const char *mtab)
{
	FILE *mntfp;
	struct mntent *mntent;
	struct stat stbuf;

	mntfp = setmntent(mtab, "r");
	if ( mntfp != NULL ) {
		char *tmp;
		char *mnt_type;
		char *mnt_dev;

		while ( (mntent=getmntent(mntfp)) != NULL ) {
			mnt_type = malloc(strlen(mntent->mnt_type) + 1);
			if (mnt_type == NULL)
				continue;  /* maybe you'll get lucky next time. */

			mnt_dev = malloc(strlen(mntent->mnt_fsname) + 1);
			if (mnt_dev == NULL) {
				free(mnt_type);
				continue;
			}

			strcpy(mnt_type, mntent->mnt_type);
			strcpy(mnt_dev, mntent->mnt_fsname);

			/* Handle "supermount" filesystem mounts */
			if ( strcmp(mnt_type, MNTTYPE_SUPER) == 0 ) {
				tmp = strstr(mntent->mnt_opts, "fs=");
				if ( tmp ) {
					free(mnt_type);
					mnt_type = strdup(tmp + strlen("fs="));
					if ( mnt_type ) {
						tmp = strchr(mnt_type, ',');
						if ( tmp ) {
							*tmp = '\0';
						}
					}
				}
				tmp = strstr(mntent->mnt_opts, "dev=");
				if ( tmp ) {
					free(mnt_dev);
					mnt_dev = strdup(tmp + strlen("dev="));
					if ( mnt_dev ) {
						tmp = strchr(mnt_dev, ',');
						if ( tmp ) {
							*tmp = '\0';
						}
					}
				}
			}
			if ( strcmp(mnt_type, MNTTYPE_CDROM) == 0 ) {
#ifdef DEBUG_CDROM
  fprintf(stderr, "Checking mount path from %s: %s mounted on %s of %s\n",
	mtab, mnt_dev, mntent->mnt_dir, mnt_type);
#endif
				if (CheckDrive(mnt_dev, mnt_type, &stbuf) > 0) {
					AddDrive(mnt_dev, &stbuf);
				}
			}
			free(mnt_dev);
			free(mnt_type);
		}
		endmntent(mntfp);
	}
}
Пример #29
0
static int
main_swapoff(int argc, char *argv[]) {
	FILE *fp;
	struct mntent *fstab;
	int status = 0;
	int c, i;

	while ((c = getopt_long(argc, argv, "ahvVL:U:",
				 longswapoffopts, NULL)) != -1) {
		switch (c) {
		case 'a':		/* all */
			++all;
			break;
		case 'h':		/* help */
			swapoff_usage(stdout, 0);
			break;
		case 'v':		/* be chatty */
			++verbose;
			break;
		case 'V':		/* version */
			printf("%s (%s)\n", progname, PACKAGE_STRING);
			exit(0);
		case 'L':
			addl(optarg);
			break;
		case 'U':
			addu(optarg);
			break;
		case 0:
			break;
		case '?':
		default:
			swapoff_usage(stderr, 1);
		}
	}
	argv += optind;

	if (!all && !llct && !ulct && *argv == NULL)
		swapoff_usage(stderr, 2);

	/*
	 * swapoff any explicitly given arguments.
	 * Complain in case the swapoff call fails.
	 */
	for (i = 0; i < llct; i++)
		status |= swapoff_by_label(llist[i], !QUIET);

	for (i = 0; i < ulct; i++)
		status |= swapoff_by_uuid(ulist[i], !QUIET);

	while (*argv != NULL)
		status |= do_swapoff(*argv++, !QUIET, !CANONIC);

	if (all) {
		/*
		 * In case /proc/swaps exists, unswap stuff listed there.
		 * We are quiet but report errors in status.
		 * Errors might mean that /proc/swaps
		 * exists as ordinary file, not in procfs.
		 * do_swapoff() exits immediately on EPERM.
		 */
		read_proc_swaps();
		for(i=0; i<numSwaps; i++)
			status |= do_swapoff(swapFiles[i], QUIET, CANONIC);

		/*
		 * Unswap stuff mentioned in /etc/fstab.
		 * Probably it was unmounted already, so errors are not bad.
		 * Doing swapoff -a twice should not give error messages.
		 */
		fp = setmntent(_PATH_FSTAB, "r");
		if (fp == NULL) {
			int errsv = errno;
			fprintf(stderr, _("%s: cannot open %s: %s\n"),
				progname, _PATH_FSTAB, strerror(errsv));
			exit(2);
		}
		while ((fstab = getmntent(fp)) != NULL) {
			const char *special;

			if (!streq(fstab->mnt_type, MNTTYPE_SWAP))
				continue;

			special = fsprobe_get_devname(fstab->mnt_fsname);
			if (!special)
				continue;

			if (!is_in_proc_swaps(special))
				do_swapoff(special, QUIET, CANONIC);
		}
		fclose(fp);
	}

	return status;
}
Пример #30
0
static int parse_fstab(bool initrd) {
        _cleanup_endmntent_ FILE *f = NULL;
        const char *fstab_path;
        struct mntent *me;
        int r = 0;

        fstab_path = initrd ? "/sysroot/etc/fstab" : "/etc/fstab";
        f = setmntent(fstab_path, "re");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                log_error("Failed to open %s: %m", fstab_path);
                return -errno;
        }

        while ((me = getmntent(f))) {
                _cleanup_free_ char *where = NULL, *what = NULL;
                int k;

                if (initrd && !mount_in_initrd(me))
                        continue;

                what = fstab_node_to_udev_node(me->mnt_fsname);
                if (!what)
                        return log_oom();

                if (detect_container(NULL) > 0 && is_device_path(what)) {
                        log_info("Running in a container, ignoring fstab device entry for %s.", what);
                        continue;
                }

                where = initrd ? strappend("/sysroot/", me->mnt_dir) : strdup(me->mnt_dir);
                if (!where)
                        return log_oom();

                if (is_path(where))
                        path_kill_slashes(where);

                log_debug("Found entry what=%s where=%s type=%s", what, where, me->mnt_type);

                if (streq(me->mnt_type, "swap"))
                        k = add_swap(what, me);
                else {
                        bool noauto, nofail, automount;
                        const char *post;

                        noauto = !!hasmntopt(me, "noauto");
                        nofail = !!hasmntopt(me, "nofail");
                        automount =
                                  hasmntopt(me, "comment=systemd.automount") ||
                                  hasmntopt(me, "x-systemd.automount");

                        if (initrd)
                                post = SPECIAL_INITRD_FS_TARGET;
                        else if (mount_in_initrd(me))
                                post = SPECIAL_INITRD_ROOT_FS_TARGET;
                        else if (mount_is_network(me))
                                post = SPECIAL_REMOTE_FS_TARGET;
                        else
                                post = SPECIAL_LOCAL_FS_TARGET;

                        k = add_mount(what,
                                      where,
                                      me->mnt_type,
                                      me->mnt_opts,
                                      me->mnt_passno,
                                      noauto,
                                      nofail,
                                      automount,
                                      post,
                                      fstab_path);
                }

                if (k < 0)
                        r = k;
        }

        return r;
}