コード例 #1
0
ファイル: sundries.c プロジェクト: glycerine/shore-mt
/* Update the mtab by removing any DIR entries and replace it with INSTEAD.  */
void
update_mtab (const char *dir, struct mntent *instead)
{
  struct mntent *mnt;
  struct mntent *next;
  int added = 0;

  open_mtab ("r");

  if ((F_temp = setmntent (MOUNTED_TEMP, "w")) == NULL)
    die (2, "can't open %s: %s", MOUNTED_TEMP, strerror (errno));
  
  while ((mnt = getmntent (F_mtab)))
    {
      next = streq (mnt->mnt_dir, dir) ? (added++, instead) : mnt;
      if (next && addmntent(F_temp, next) == 1)
	die (1, "error writing %s: %s", MOUNTED_TEMP, strerror (errno));
    }
  if (instead && !added)
    addmntent(F_temp, instead);

  endmntent (F_mtab);
  if (fchmod (fileno (F_temp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
    die (1, "error changing mode of %s: %s", MOUNTED_TEMP, strerror (errno));
  endmntent (F_temp);

  if (rename (MOUNTED_TEMP, MOUNTED) < 0)
    die (1, "can't rename %s to %s: %s",
	 MOUNTED_TEMP, MOUNTED, strerror(errno));
}
コード例 #2
0
ファイル: mtab.c プロジェクト: cvmfs/aufs2-util
static void append_mtab(FILE *fp, FILE *ofp, struct mntent *ent)
{
	int err;
	struct mntent *p;

	while ((p = getmntent(ofp))) {
		err = addmntent(fp, p);
		if (err)
			AuFin("addmntent");
	}

	err = addmntent(fp, ent);
	if (err)
		AuFin("addmntent");
}
コード例 #3
0
ファイル: commandtool.cpp プロジェクト: pengxiaojun/grdisk
int commandtool::automnt_part(const blockdevice *block, QString mount_point)
{
    struct mntent *mnt;
    FILE *fp;
    fp = setmntent(FSTAB_FILE, "r");

    if (fp == NULL)
    {
        util::log(QString("automount %1 error %2").arg(block->device).arg(errno));
        return -1;
    }

    while ((mnt = getmntent(fp)))
    {
        QString fsname  = QString(mnt->mnt_fsname);
        foreach(const QString& symlink, block->symlinks)
        {
            if (fsname == symlink)
            {
                endmntent(fp);
                return 0;   //already exist;
            }
        }
    }
    endmntent(fp);
    //add mmntent
    QString device_path = QString("%1%2").arg(DEVICE_PATH_PREFIX).arg(block->id);
    bool found = false;

    foreach(const QString& symlink, block->symlinks)
    {
        if (symlink == device_path)
        {
            found = true;
            break;
        }
    }

    if (!found){
        util::log(QString("automount %1 at can not found in %2 symbol links").arg(device_path).arg(block->device));
    }
    struct mntent *m = (mntent*)calloc(1,sizeof(mntent));
    m->mnt_fsname   = strdup(device_path.toAscii().data());
    m->mnt_dir      = strdup(mount_point.toAscii().data());
    m->mnt_type     = strdup("ext4");
    m->mnt_opts     = strdup("defaults,nofail,user");
    m->mnt_passno   = 2;
    m->mnt_freq     = 0;

    util::log(QString("mnt=%1 fsname=%2").arg(mount_point).arg(device_path));
    fp = setmntent(FSTAB_FILE,"a+"); //open file for describing the mounted filesystems
    addmntent(fp,m);
    endmntent(fp);
    free(m->mnt_dir);
    free(m->mnt_fsname);
    free(m->mnt_type);
    free(m->mnt_opts);
    free(m);
    return 0;
}
コード例 #4
0
ファイル: mount_mtfs.c プロジェクト: ddn-lixi/mtfs
static int
update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
                  int flags, int freq, int pass)
{
	FILE *fp;
	struct mntent mnt;
	int rc = 0;

	mnt.mnt_fsname = spec;
	mnt.mnt_dir = mtpt;
	mnt.mnt_type = type;
	mnt.mnt_opts = opts ? opts : "";
	mnt.mnt_freq = freq;
	mnt.mnt_passno = pass;

	fp = setmntent(MOUNTED, "a+");
	if (fp == NULL) {
		fprintf(stderr, "%s: setmntent(%s): %s:",
		        progname, MOUNTED, strerror (errno));
		rc = 16;
	} else {
		if ((addmntent(fp, &mnt)) == 1) {
			fprintf(stderr, "%s: addmntent: %s:",
				progname, strerror (errno));
			rc = 16;
		}
		endmntent(fp);
	}

	return rc;
}
コード例 #5
0
ファイル: mtab_linux.c プロジェクト: enukane/netbsd-src
/*
 * Append a mntent structure to the
 * current mount table.
 */
void
write_mntent(mntent_t *mp, const char *mnttabname)
{
  int retries = 0;
  FILE *mfp;

  if (!mtab_is_writable()) {
    return;
  }

 enfile:
  mfp = open_locked_mtab(mnttabname, "a", mp->mnt_dir);
  if (mfp) {
    mtab_stripnl(mp->mnt_opts);
    if (addmntent(mfp, mp))
      plog(XLOG_ERROR, "Couldn't write %s: %m", mnttabname);
    if (fflush(mfp))
      plog(XLOG_ERROR, "Couldn't flush %s: %m", mnttabname);
    (void) endmntent(mfp);
  } else {
    if (errno == ENFILE && retries < NFILE_RETRIES) {
      sleep(1);
      goto enfile;
    }
    plog(XLOG_ERROR, "setmntent(\"%s\", \"a\"): %m", mnttabname);
  }

  unlock_mntlist();
}
コード例 #6
0
ファイル: fusermount.c プロジェクト: rolivia/OS-Project
static int add_mount(const char *fsname, const char *mnt, const char *type,
                     const char *opts)
{
    int res;
    const char *mtab = _PATH_MOUNTED;
    struct mntent ent;
    FILE *fp;

    if (check_name(fsname) == -1 || check_name(mnt) == -1 ||
        check_name(type) == -1 || check_name(opts) == -1)
        return -1;

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

    ent.mnt_fsname = (char *) fsname;
    ent.mnt_dir = (char *) mnt;
    ent.mnt_type = (char *) type;
    ent.mnt_opts = (char *) opts;
    ent.mnt_freq = 0;
    ent.mnt_passno = 0;
    res = addmntent(fp, &ent);
    if (res != 0) {
        fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname,
                mtab, strerror(errno));
        return -1;
    }

    endmntent(fp);
    return 0;
}
コード例 #7
0
ファイル: mount.c プロジェクト: blueprintmrk/stablebox
static int mount_it_now(struct mntent *mp, int vfsflags, char *filteropts)
{
	int rc;

	if (fakeIt) { return 0; }

	// Mount, with fallback to read-only if necessary.

	for(;;) {
		rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type,
				vfsflags, filteropts);
		if(!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS))
			break;
		bb_error_msg("%s is write-protected, mounting read-only",
				mp->mnt_fsname);
		vfsflags |= MS_RDONLY;
	}

	// Abort entirely if permission denied.

	if (rc && errno == EPERM)
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);

	/* If the mount was successful, and we're maintaining an old-style
	 * mtab file by hand, add the new entry to it now. */

	if(ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc) {
		FILE *mountTable = setmntent(bb_path_mtab_file, "a+");
		int i;

		if(!mountTable)
			bb_error_msg("No %s\n",bb_path_mtab_file);

		// Add vfs string flags

		for(i=0; mount_options[i].flags != MS_REMOUNT; i++)
			if (mount_options[i].flags > 0)
				append_mount_options(&(mp->mnt_opts),
// Shut up about the darn const.  It's not important.  I don't care.
						(char *)mount_options[i].name);

		// Remove trailing / (if any) from directory we mounted on

		i = strlen(mp->mnt_dir);
		if(i>1 && mp->mnt_dir[i-1] == '/') mp->mnt_dir[i-1] = 0;

		// Write and close.

		if(!mp->mnt_type || !*mp->mnt_type) mp->mnt_type="--bind";
		addmntent(mountTable, mp);
		endmntent(mountTable);
		if (ENABLE_FEATURE_CLEAN_UP)
			if(strcmp(mp->mnt_type,"--bind")) mp->mnt_type = 0;
	}

	return rc;
}
コード例 #8
0
ファイル: mntpt_mntent.c プロジェクト: MarkMielke/brltty
int
addMountEntry (FILE *table, MountEntry *entry) {
#ifdef HAVE_ADDMNTENT
  if (addmntent(table, entry)) {
    logMessage(LOG_ERR, "mounts table entry add error: %s[%s] -> %s: %s",
               entry->mnt_type, entry->mnt_fsname, entry->mnt_dir, strerror(errno));
    return 0;
  }
#endif /* HAVE_ADDMNTENT */
  return 1;
}
コード例 #9
0
ファイル: mtab.c プロジェクト: cvmfs/aufs2-util
/* todo: there are some cases which options are not changed */
static void update_mtab(FILE *fp, char *mntpnt, int do_remount, int do_verbose)
{
	int err;
	long pos;
	FILE *ofp;
	struct mntent ent, *p;

	/* prohibit updating mount options for this mntpnt */
	au_plink_maint(mntpnt);
	err = au_proc_getmntent(mntpnt, &ent);
	if (err)
		AuFin("no such mount point");

	ofp = setmntent(MTab, "r");
	if (!ofp)
		AuFin(MTab);

	if (do_remount) {
		/* find the last one */
		pos = -1;
		while ((p = getmntent(ofp))) {
			if (!strcmp(p->mnt_dir, mntpnt))
				pos = ftell(ofp);
		}
		rewind(ofp);

		if (pos > 0) {
			while ((p = getmntent(ofp))) {
				if (ftell(ofp) == pos) {
					/* replace the line */
					p = &ent;
					pos = -1;
				}
				err = addmntent(fp, p);
				if (err)
					AuFin("addmntent");
			}
			if (pos > 0)
				AuFin("internal error");
		} else
			append_mtab(fp, ofp, &ent);
	} else
		append_mtab(fp, ofp, &ent);

	endmntent(ofp); /* ignore */
	au_plink_maint(NULL);
	if (do_verbose)
		au_print_ent(&ent);
}
コード例 #10
0
ファイル: unmount_volume.c プロジェクト: Salan54/zuluCrypt
int zuluCrypRemoveEntryFromMtab( const char * m_point ) 
{
#if USE_NEW_LIBMOUNT_API
	struct libmnt_lock * lock ;
#else
	mnt_lock * lock ;
#endif
	struct mntent * mt ;
	
	FILE * f ;
	FILE * g ;	
	
	size_t dir_len = strlen( m_point ) ;
	
	int h ;

	lock = mnt_new_lock( "/etc/mtab~",getpid() ) ;
	
	f = setmntent( "/etc/mtab","r" ) ;
	
	if( mnt_lock_file( lock ) != 0 ){
		h = 4 ;
	}else{
		g = setmntent( "/etc/mtab-zuluCrypt","w" ) ;
		while( ( mt = getmntent( f ) ) != NULL ){
			if( StringPrefixMatch( mt->mnt_dir,m_point,dir_len ) ){
				/*
				 * an entry we want to delete,skip it
				 */
				;
			}else{
				addmntent( g,mt ) ;
			}
		}

		endmntent( g ) ;
		rename( "/etc/mtab-zuluCrypt","/etc/mtab" ) ;
		chown( "/etc/mtab",0,0 ) ;
		chmod( "/etc/mtab",S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH ) ;
		mnt_unlock_file( lock ) ;
		h = 0 ;
	}
	
	endmntent( f ) ;
	mnt_free_lock( lock ) ;
	return h ;
}
コード例 #11
0
ファイル: fusermount.c プロジェクト: StyXman/Trieste
static int add_mount(const char *dev, const char *mnt, const char *type)
{
    int res;
    const char *mtab = _PATH_MOUNTED;
    struct mntent ent;
    FILE *fp;
    char *opts;

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

    if(getuid() != 0) {
        const char *user = get_user_name();
        if(user == NULL)
            return -1;

        opts = malloc(strlen(user) + 128);
        if(opts != NULL)
            sprintf(opts, "rw,nosuid,nodev,user=%s", user);
    }
    else
        opts = strdup("rw,nosuid,nodev");

    if(opts == NULL)
        return -1;

    ent.mnt_fsname = (char *) dev;
    ent.mnt_dir = (char *) mnt;
    ent.mnt_type = (char *) type;
    ent.mnt_opts = opts;
    ent.mnt_freq = 0;
    ent.mnt_passno = 0;
    res = addmntent(fp, &ent);
    if(res != 0) {
        fprintf(stderr, "%s: failed to add entry to %s: %s\n", progname,
                mtab, strerror(errno));
        return -1;
    }

    endmntent(fp);
    return 0;
}
コード例 #12
0
ファイル: sundries.c プロジェクト: LambdaCalculus379/SLS-1.02
/* Create mtab with a root entry.  */
static void
create_mtab (void)
{
  struct mntent *fstab;

  if ((F_mtab = setmntent (MOUNTED, "a+")) == NULL)
    die (1, "mount: can't open %s for writing: %s", MOUNTED, strerror (errno));

  /* Find the root entry by looking it up in fstab, which might be wrong.
     We could statfs "/" followed by a slew of stats on /dev/ but then
     we'd have to unparse the mount options as well....  */
  if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root")))
    {
      if (addmntent (F_mtab, fstab) == 1)
	die (1, "mount: error writing %s: %s", MOUNTED, strerror (errno));
    }
  endmntent (F_mtab);
}
コード例 #13
0
void write_mtab(char *blockDevice, char *directory,
				char *filesystemType, long flags, char *string_flags)
{
	FILE *mountTable = setmntent(mtab_file, "a+");
	struct mntent m;

	if (mountTable == 0) {
		perror_msg("%s", mtab_file);
		return;
	}
	if (mountTable) {
		int length = strlen(directory);

		if (length > 1 && directory[length - 1] == '/')
			directory[length - 1] = '\0';

		if (filesystemType == 0) {
			struct mntent *p = find_mount_point(blockDevice, "/proc/mounts");

			if (p && p->mnt_type)
				filesystemType = p->mnt_type;
		}
		m.mnt_fsname = blockDevice;
		m.mnt_dir = directory;
		m.mnt_type = filesystemType ? filesystemType : "default";

		if (*string_flags) {
			m.mnt_opts = string_flags;
		} else {
			if ((flags | MS_RDONLY) == flags)
				m.mnt_opts = "ro";
			else
				m.mnt_opts = "rw";
		}

		m.mnt_freq = 0;
		m.mnt_passno = 0;
		addmntent(mountTable, &m);
		endmntent(mountTable);
	}
}
コード例 #14
0
void erase_mtab(const char *name)
{
	struct mntent entries[20];
	int count = 0;
	FILE *mountTable = setmntent(mtab_file, "r");
	struct mntent *m;

	/* Check if reading the mtab file failed */
	if (mountTable == 0
			/* Bummer.  fall back on trying the /proc filesystem */
			&& (mountTable = setmntent("/proc/mounts", "r")) == 0) {
		perror_msg("%s", mtab_file);
		return;
	}

	while ((m = getmntent(mountTable)) != 0) {
		entries[count].mnt_fsname = strdup(m->mnt_fsname);
		entries[count].mnt_dir = strdup(m->mnt_dir);
		entries[count].mnt_type = strdup(m->mnt_type);
		entries[count].mnt_opts = strdup(m->mnt_opts);
		entries[count].mnt_freq = m->mnt_freq;
		entries[count].mnt_passno = m->mnt_passno;
		count++;
	}
	endmntent(mountTable);
	if ((mountTable = setmntent(mtab_file, "w"))) {
		int i;

		for (i = 0; i < count; i++) {
			int result = (strcmp(entries[i].mnt_fsname, name) == 0
						  || strcmp(entries[i].mnt_dir, name) == 0);

			if (result)
				continue;
			else
				addmntent(mountTable, &entries[i]);
		}
		endmntent(mountTable);
	} else if (errno != EROFS)
		perror_msg("%s", mtab_file);
}
コード例 #15
0
ファイル: mtab.c プロジェクト: dzo/busybox
void FAST_FUNC erase_mtab(const char *name)
{
	struct mntent *entries;
	int i, count;
	FILE *mountTable;
	struct mntent *m;

	mountTable = setmntent(bb_path_mtab_file, "r");
	/* Bummer. Fall back on trying the /proc filesystem */
	if (!mountTable) mountTable = setmntent("/proc/mounts", "r");
	if (!mountTable) {
		bb_perror_msg(bb_path_mtab_file);
		return;
	}

	entries = NULL;
	count = 0;
	while ((m = getmntent(mountTable)) != 0) {
		entries = xrealloc_vector(entries, 3, count);
		entries[count].mnt_fsname = xstrdup(m->mnt_fsname);
		entries[count].mnt_dir = xstrdup(m->mnt_dir);
		entries[count].mnt_type = xstrdup(m->mnt_type);
		entries[count].mnt_opts = xstrdup(m->mnt_opts);
		entries[count].mnt_freq = m->mnt_freq;
		entries[count].mnt_passno = m->mnt_passno;
		count++;
	}
	endmntent(mountTable);

//TODO: make update atomic
	mountTable = setmntent(bb_path_mtab_file, "w");
	if (mountTable) {
		for (i = 0; i < count; i++) {
			if (strcmp(entries[i].mnt_fsname, name) != 0
			 && strcmp(entries[i].mnt_dir, name) != 0)
				addmntent(mountTable, &entries[i]);
		}
		endmntent(mountTable);
	} else if (errno != EROFS)
		bb_perror_msg(bb_path_mtab_file);
}
コード例 #16
0
ファイル: diodmount.c プロジェクト: pipcet/diod
static int
_update_mtab (char *options, char *spec, char *dir)
{
    uid_t saved_euid = geteuid ();
    FILE *f;
    int ret = 0;
    struct mntent mnt;

    mnt.mnt_fsname = spec;
    mnt.mnt_dir = dir;
    mnt.mnt_type = "diod";
    mnt.mnt_opts = options;
    mnt.mnt_freq = 0;
    mnt.mnt_passno = 0;

    if (seteuid (0) < 0) {
        err ("failed to set effective uid to root");
        goto done;
    }
    if (!(f = setmntent (_PATH_MOUNTED, "a"))) {
        err (_PATH_MOUNTED);
        goto done;
    }
    if (addmntent (f, &mnt) != 0) {
        msg ("failed to add entry to %s", _PATH_MOUNTED);
        endmntent (f);
        goto done;
    }
    endmntent (f);
    if (seteuid (saved_euid) < 0) {
        err ("failed to restore effective uid to %d", saved_euid);
        goto done;
    }
    ret = 1;
done:
    return ret;
}
コード例 #17
0
ファイル: commandtool.cpp プロジェクト: pengxiaojun/grdisk
int commandtool::deautomnt_part(const blockdevice *block)
{
    const char *fstab_tmp = "/etc/fstab~";
    struct mntent *m1 = NULL;
    FILE *f1= NULL,*f2 = NULL;
    f1 = setmntent(FSTAB_FILE, "r");
    f2 = setmntent(fstab_tmp, "w+");

    if (f1 == NULL || f2 == NULL)
    {
        util::log(QString("deautomount %1 error %2").arg(block->device).arg(errno));
        return -1;
    }

    while ((m1 = getmntent(f1)))
    {
        QString fsname = QString(m1->mnt_fsname);
        bool has = false;
        foreach(const QString& symlink, block->symlinks)
        {
            if (fsname == symlink)
            {
                has = true;
                qDebug() <<symlink;
                break;
            }
        }
        if (!has)
        {
            addmntent(f2,m1);
        }
    }
    endmntent(f1);
    endmntent(f2);
    rename(fstab_tmp, FSTAB_FILE);
    return 0;
}
コード例 #18
0
static void
UpdateMtab(HgfsMountInfo *mountInfo,  // IN: Info to write into mtab
           int flags)                 // IN: Flags (read-only, etc.)
{
   struct mntent mountEnt;
   FILE *mountFile;
   struct passwd *password;
   char *userName = NULL;

   ASSERT(mountInfo);

   mountFile = setmntent(MOUNTED, "a+");
   if (mountFile == NULL) {
      printf("Could not open mtab for appending, continuing sans mtab\n");
      return;
   }

   /* We only care about the mounting user if it isn't root. */
   if (getuid() != 0) {
      password = getpwuid(getuid());
      if (password == NULL) {
         printf("Could not get user for mounting uid, skipping user entry\n");
      } else {
         userName = password->pw_name;
      }
   }

   /*
    * Create the mtab entry to be written. We'll go ahead and try to write
    * even if we fail to allocate the mount options.
    */
   mountEnt.mnt_fsname = shareName;
   mountEnt.mnt_dir = mountPoint;
   mountEnt.mnt_type = HGFS_NAME;
   mountEnt.mnt_freq = 0;
   mountEnt.mnt_passno = 0;
   mountEnt.mnt_opts = malloc(MOUNT_OPTS_BUFFER_SIZE);
   if (mountEnt.mnt_opts) {
      char *ttlString;

      memset(mountEnt.mnt_opts, 0, MOUNT_OPTS_BUFFER_SIZE);

      /*
       * These are typically the displayed options in /etc/mtab (note that not
       * all options are typically displayed, just those the user may find
       * interesting).
       */
      if (flags & MS_RDONLY) {
         Str_Strcat(mountEnt.mnt_opts, "ro", MOUNT_OPTS_BUFFER_SIZE);
      } else {
         Str_Strcat(mountEnt.mnt_opts, "rw", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_NOSUID) {
         Str_Strcat(mountEnt.mnt_opts, ",nosuid", MOUNT_OPTS_BUFFER_SIZE);
      }
#ifdef MS_NODEV
      if (flags & MS_NODEV) {
         Str_Strcat(mountEnt.mnt_opts, ",nodev", MOUNT_OPTS_BUFFER_SIZE);
      }
#endif
      if (flags & MS_NOEXEC) {
         Str_Strcat(mountEnt.mnt_opts, ",noexec", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_SYNCHRONOUS) {
         Str_Strcat(mountEnt.mnt_opts, ",sync", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_MANDLOCK) {
         Str_Strcat(mountEnt.mnt_opts, ",mand", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_NOATIME) {
         Str_Strcat(mountEnt.mnt_opts, ",noatime", MOUNT_OPTS_BUFFER_SIZE);
      }
      if (flags & MS_NODIRATIME) {
         Str_Strcat(mountEnt.mnt_opts, ",nodiratime", MOUNT_OPTS_BUFFER_SIZE);
      }

      if (userName != NULL) {
         Str_Strcat(mountEnt.mnt_opts, ",user="******"%u", mountInfo->ttl);
      if (ttlString != NULL) {
         Str_Strcat(mountEnt.mnt_opts, ",ttl=", MOUNT_OPTS_BUFFER_SIZE);
         Str_Strcat(mountEnt.mnt_opts, ttlString, MOUNT_OPTS_BUFFER_SIZE);
         free(ttlString);
      } else {
         printf("Could not allocate memory for ttl entry in mtab, "
                "continuing\n");
      }
   }

   /* Add the entry and close. */
   if (addmntent(mountFile, &mountEnt)) {
      printf("Could not add entry to mtab, continuing\n");
   }
   endmntent(mountFile);
   if (mountEnt.mnt_opts) {
      free(mountEnt.mnt_opts);
   }
}
コード例 #19
0
ファイル: afsd_kernel.c プロジェクト: jisqyv/openafs
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;
}
コード例 #20
0
ファイル: umount.cifs.c プロジェクト: berte/mediaplayer
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;
}
コード例 #21
0
ファイル: mount.c プロジェクト: AlickHill/Lantern
// Perform actual mount of specific filesystem at specific location.
// NB: mp->xxx fields may be trashed on exit
static int mount_it_now(struct mntent *mp, int vfsflags, char *filteropts)
{
	int rc = 0;

	if (fakeIt) goto mtab;

	// Mount, with fallback to read-only if necessary.

	for (;;) {
		rc = mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type,
				vfsflags, filteropts);
		if (!rc || (vfsflags&MS_RDONLY) || (errno!=EACCES && errno!=EROFS))
			break;
		bb_error_msg("%s is write-protected, mounting read-only",
				mp->mnt_fsname);
		vfsflags |= MS_RDONLY;
	}

	// Abort entirely if permission denied.

	if (rc && errno == EPERM)
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);

	/* If the mount was successful, and we're maintaining an old-style
	 * mtab file by hand, add the new entry to it now. */
 mtab:
	if (ENABLE_FEATURE_MTAB_SUPPORT && useMtab && !rc && !(vfsflags & MS_REMOUNT)) {
		char *fsname;
		FILE *mountTable = setmntent(bb_path_mtab_file, "a+");
		int i;

		if (!mountTable) {
			bb_error_msg("no %s",bb_path_mtab_file);
			goto ret;
		}

		// Add vfs string flags

		for (i=0; mount_options[i].flags != MS_REMOUNT; i++)
			if (mount_options[i].flags > 0 && (mount_options[i].flags & vfsflags))
				append_mount_options(&(mp->mnt_opts), mount_options[i].name);

		// Remove trailing / (if any) from directory we mounted on

		i = strlen(mp->mnt_dir) - 1;
		if (i > 0 && mp->mnt_dir[i] == '/') mp->mnt_dir[i] = 0;

		// Convert to canonical pathnames as needed

		mp->mnt_dir = bb_simplify_path(mp->mnt_dir);
		fsname = 0;
		if (!mp->mnt_type || !*mp->mnt_type) { /* bind mount */
			mp->mnt_fsname = fsname = bb_simplify_path(mp->mnt_fsname);
			mp->mnt_type = (char*)"bind";
		}
		mp->mnt_freq = mp->mnt_passno = 0;

		// Write and close.

		addmntent(mountTable, mp);
		endmntent(mountTable);
		if (ENABLE_FEATURE_CLEAN_UP) {
			free(mp->mnt_dir);
			free(fsname);
		}
	}
 ret:
	return rc;
}
コード例 #22
0
ファイル: libzfs_mtab.c プロジェクト: glycerine/zfs
/* Add entry in the /etc/mtab */
int zfs_linux_add_entry(char *mountpoint, char *zfs_name, const char *mtab_file,
	char *mountopt)
{
	struct mntent mnt;
	FILE *mtab = NULL;
	int lock_fd;
	
	bzero(&mnt, sizeof(struct mntent));

	mnt.mnt_dir    =  mountpoint;
	mnt.mnt_type   = "zfs";
	mnt.mnt_fsname = zfs_name;
	if (!system("selinuxenabled > /dev/null 2>&1")) {
		mnt.mnt_opts = (strcmp(mountopt, MNTOPT_RW) == 0) ? 
			"rw,context=\"system_u:object_r:file_t:s0\"" :
			"ro,context=\"system_u:object_r:file_t:s0\"";
	} else {
		mnt.mnt_opts = mountopt;
	}
	mnt.mnt_freq   = 0;
	mnt.mnt_passno = 0;

	if ((lock_fd = open(FLOCK_PATH, O_RDONLY)) < 0) {
		fprintf(stderr, "%s(%d): open: %s.\n", __FUNCTION__, __LINE__, 
				strerror(errno));
		return -1;
	}

	if (flock(lock_fd, LOCK_EX) < 0) {
		fprintf(stderr, "%s(%d): flock: %s.\n", __FUNCTION__, __LINE__, 
				strerror(errno));
		close(lock_fd);
		return -1;
	}

	if (NULL == (mtab = setmntent(mtab_file, "a+"))) {
		flock(lock_fd, LOCK_UN);
		close(lock_fd);
		return -1;
	}

	if (addmntent(mtab, &mnt) != 0) {
		fprintf(stderr, "%s(%d): addmntent: %s.\n", __FUNCTION__, __LINE__, 
				strerror(errno));
		endmntent(mtab);
		flock(lock_fd, LOCK_UN);
		close(lock_fd);
		return -1;
	}

	endmntent(mtab);

	if (flock(lock_fd, LOCK_UN) < 0) {
		fprintf(stderr, "%s(%d): flock: %s.\n", __FUNCTION__, __LINE__, 
				strerror(errno));
		close(lock_fd);
		return -1;
	}
	close(lock_fd);

	return 0;
}
コード例 #23
0
ファイル: mtab_linux.c プロジェクト: enukane/netbsd-src
/*
 * Write out a mount list
 */
void
rewrite_mtab(mntlist *mp, const char *mnttabname)
{
  FILE *mfp;
  int error = 0;
  char tmpname[64];
  int retries;
  int tmpfd;
  char *cp;
  char mcp[128];

  if (!mtab_is_writable()) {
    return;
  }

  /*
   * Concoct a temporary name in the same directory as the target mount
   * table so that rename() will work.
   */
  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);
}
コード例 #24
0
ファイル: hugeadm.c プロジェクト: Maffblaster/libhugetlbfs
int mount_dir(char *path, char *options, mode_t mode, uid_t uid, gid_t gid)
{
	struct passwd *pwd;
	struct group *grp;
	struct mntent entry;
	FILE *mounts;
        char dummy;
        int useMtab;

	struct mount_list *list, *previous;

	list = collect_active_mounts(NULL);

	if (list && check_if_already_mounted(list, path)) {
		WARNING("Directory %s is already mounted.\n", path);

		while (list) {
			previous = list;
			list = list->next;
			free(previous);
		}
		return 0;
	}

	while (list) {
		previous = list;
		list = list->next;
		free(previous);
	}

	if (opt_dry_run) {
		pwd = getpwuid(uid);
		grp = getgrgid(gid);
		printf("mount -t %s none %s -o %s\n", FS_NAME,
			path, options);
		printf("chown %s:%s %s\n", pwd->pw_name, grp->gr_name,
			path);
		printf("chmod %o %s\n", mode, path);
	} else {
		if (mount("none", path, FS_NAME, 0, options)) {
			ERROR("Unable to mount %s, error: %s\n",
				path, strerror(errno));
			return 1;
		}

          /* Check if mtab is a symlink */
          useMtab = (readlink(MOUNTED, &dummy, 1) < 0);
          if (useMtab) {
			mounts = setmntent(MOUNTED, "a+");
			if (mounts) {
				entry.mnt_fsname = FS_NAME;
				entry.mnt_dir = path;
				entry.mnt_type = FS_NAME;
				entry.mnt_opts = options;
				entry.mnt_freq = 0;
				entry.mnt_passno = 0;
				if (addmntent(mounts, &entry))
					WARNING("Unable to add entry %s to %s, error: %s\n",
						path, MOUNTED, strerror(errno));
				endmntent(mounts);
			} else {
				WARNING("Unable to open %s, error: %s\n",
					MOUNTED, strerror(errno));
			}
		}

		if (chown(path, uid, gid)) {
			ERROR("Unable to change ownership of %s, error: %s\n",
				path, strerror(errno));
			return 1;
		}

		if (chmod(path, mode)) {
			ERROR("Unable to set permissions on %s, error: %s\n",
				path, strerror(errno));
			return 1;
		}
	}
	return 0;
}
コード例 #25
0
int main (int argc, char **argv)
{
    char                *dir;
    char                *host;
    char                *ports;
    int                 port;
    struct hostent      *h;
    int                 fstype;
    FILE                *mtabf;
    struct mntent       mnt =
    {
        0,
        0,
        NSD_FSTYPE,
        "soft,timeo=100,retrans=2",
        0,
        0,
    };

    if (argc != 4)
        usage ();

    dir = argv[1];
    host = argv[2];
    port = atoi ((ports = argv[3]));

    /* Prepare for host lookup. */
    memset ((void *) &sin, 0, sizeof (sin));
    sin.sin_family = 2;
    sin.sin_port = port;

    /* Look up the host. */
    if (inet_aton (host, &sin.sin_addr))
        ;
    else if ((h = gethostbyname (host)))
    {
        unsigned long   *l = (unsigned long *) *(h->h_addr_list);
        sin.sin_addr.s_addr = l[0];
    }
    else
    {
        fprintf (stderr, "Cannot resolve host %s.\n", host);
        return 1;
    }

    /* Get filesystem type index for nsd filesystem type. */
    if ((fstype = sysfs (GETFSIND, NSD_FSTYPE)) < 0)
    {
        perror ("sysfs (" NSD_FSTYPE ")");
        return 1;
    }

    fprintf (stderr, "Mounting nsd " NSD_FSTYPE " fs from %s(%s):%d onto %s\n",
        host, inet_ntoa (sin.sin_addr), port, dir);

    /* These flags are documented in /usr/include/sys/mount.h. MS_DOXATTR
       means "tell server to trust us with attributes" and MS_DATA means
       "6-argument mount".

       MS_DOXATTR is a mount option in IRIX 6.4 and up. The attack doesn't
       seem to work without this option. So even though this program will
       compile on IRIX 6.2, you need to use an IRIX 6.4 or higher OS to
       attack nsd. */
    if (mount (dir, dir, MS_DOXATTR|MS_DATA, (char *) fstype, &nx, sizeof (nx))
        != 0)
    {
        perror ("mount");
        return 1;
    }

    /* Record mount point in /etc/mtab. */
    mnt.mnt_fsname = malloc (strlen (host) + sizeof (":nsd@") + strlen (ports) + 1);
    sprintf (mnt.mnt_fsname, "%s:nsd@%s", host, ports);
    mnt.mnt_dir = dir;
    if (!(mtabf = setmntent (MTAB_FILE, "r+")))
    {
        perror ("setmntent");
        return 1;
    }
    if (addmntent (mtabf, &mnt) < 0)
    {
        perror ("addmntent");
        return 1;
    }
    if (endmntent (mtabf) < 0)
    {
        perror ("endmntent");
        return 1;
    }

    return 0;
}
コード例 #26
0
ファイル: mount.cifs.c プロジェクト: DeezNuts12/freestyledash
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;
	char * resolved_path;
	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;
	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':
			flags |= MS_BIND;
			break;
		case 'm':
			flags |= MS_MOVE;
			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 = 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 = 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))
                return -1;
	ipaddr = parse_server(&share_name);
	if((ipaddr == NULL) && (got_ip == 0)) {
		printf("No ip address specified and hostname not found\n");
		return -1;
	}
	
	/* BB save off path and pop after mount returns? */
	resolved_path = 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);
		return -1;
	}

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

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

	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) {
		mountpassword = getpass("Password: "******"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;
	options = malloc(optlen + 10 + 64 /* 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;
	strncat(options,"unc=",4);
	strcat(options,share_name);
	/* scan backwards and reverse direction of slash */
	temp = strrchr(options, '/');
	if(temp > options + 6)
		*temp = '\\';
	if(ipaddr) {
		strncat(options,",ip=",4);
		strcat(options,ipaddr);
	}

	if(user_name) {
		/* check for syntax like user=domain\user */
		if(got_domain == 0)
			domain_name = check_for_domain(&user_name);
		strncat(options,",user="******",domain=",8);
			strcat(options,domain_name);
		}
	}
	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);
		strncat(options,",pass="******",ver=",5);
	strcat(options,MOUNT_CIFS_VERSION_MAJOR);

	if(orgoptions) {
		strcat(options,",");
		strcat(options,orgoptions);
	}
	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");
		if(mountpassword) {
			memset(mountpassword,0,64);
		}
		return -1;
	} 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 = malloc(220);
			if(mountent.mnt_opts) {
				char * mount_user = getusername();
				memset(mountent.mnt_opts,0,200);
				if(flags & MS_RDONLY)
					strcat(mountent.mnt_opts,"ro");
				else
					strcat(mountent.mnt_opts,"rw");
				if(flags & MS_MANDLOCK)
					strcat(mountent.mnt_opts,",mand");
				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(flags & MS_SYNCHRONOUS)
					strcat(mountent.mnt_opts,",synch");
				if(mount_user) {
					if(getuid() != 0) {
						strcat(mountent.mnt_opts,",user="******"could not update mount table\n");
		}
	}
コード例 #27
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;
	const char * ipaddr = NULL;
	char * uuid = NULL;
	char * mountpoint = NULL;
	char * options = NULL;
	char * optionstail;
	char * resolved_path = NULL;
	char * temp;
	char * dev_name;
	int rc = 0;
	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;
	size_t current_len;
	int retry = 0; /* set when we have to retry mount with uppercase */
	struct addrinfo *addrhead = NULL, *addr;
	struct stat statbuf;
	struct utsname sysinfo;
	struct mntent mountent;
	struct sockaddr_in *addr4;
	struct sockaddr_in6 *addr6;
	FILE * pmntfile;

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

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

	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) {
		dev_name = argv[1];
		share_name = strndup(argv[1], MAX_UNC_LEN);
		if (share_name == NULL) {
			fprintf(stderr, "%s: %s", argv[0], strerror(ENOMEM));
			exit(EX_SYSERR);
		}
		mountpoint = argv[2];
	} else if (argc == 2) {
		if ((strcmp(argv[1], "-V") == 0) ||
		    (strcmp(argv[1], "--version") == 0))
		{
			print_cifs_mount_version();
			exit(0);
		}

		if ((strcmp(argv[1], "-h") == 0) ||
		    (strcmp(argv[1], "-?") == 0) ||
		    (strcmp(argv[1], "--help") == 0))
		{
			mount_cifs_usage();
			exit(0);
		}

		mount_cifs_usage();
		exit(EX_USAGE);
	} else {
		mount_cifs_usage();
		exit(EX_USAGE);
	}

	/* 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(EX_USAGE);
		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':
			print_cifs_mount_version();
			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(EX_USAGE);
				}
			} else {
				struct passwd *pw;

				if (!(pw = getpwnam(optarg))) {
					printf("bad user name \"%s\"\n", optarg);
					exit(EX_USAGE);
				}
				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(EX_USAGE);
				}
			} else {
				struct group *gr;

				if (!(gr = getgrnam(optarg))) {
					printf("bad user name \"%s\"\n", optarg);
					exit(EX_USAGE);
				}
				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(MOUNT_PASSWD_SIZE+1,1);
			if(mountpassword) {
				got_password = 1;
				strlcpy(mountpassword,optarg,MOUNT_PASSWD_SIZE+1);
			}
			break;
		case 'S':
			get_password_from_file(0 /* stdin */,NULL);
			break;
		case 't':
			break;
		case 'f':
			++fakemnt;
			break;
		default:
			printf("unknown mount option %c\n",c);
			mount_cifs_usage();
			exit(EX_USAGE);
		}
	}

	if((argc < 3) || (dev_name == NULL) || (mountpoint == NULL)) {
		mount_cifs_usage();
		exit(EX_USAGE);
	}

	if (getenv("PASSWD")) {
		if(mountpassword == NULL)
			mountpassword = (char *)calloc(MOUNT_PASSWD_SIZE+1,1);
		if(mountpassword) {
			strlcpy(mountpassword,getenv("PASSWD"),MOUNT_PASSWD_SIZE+1);
			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 = EX_USAGE;
		goto mount_exit;
	}
	addrhead = addr = parse_server(&share_name);
	if((addrhead == NULL) && (got_ip == 0)) {
		printf("No ip address specified and hostname not found\n");
		rc = EX_USAGE;
		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 = EX_USAGE;
		goto mount_exit;
	}

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

	if (S_ISDIR(statbuf.st_mode) == 0) {
		printf("mount error: mount point %s is not a directory\n",mountpoint);
		rc = EX_USAGE;
		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"); 
			exit(EX_USAGE);
		}
	}

	if(got_user == 0) {
		/* Note that the password will not be retrieved from the
		   USER env variable (ie user%password form) as there is
		   already a PASSWD environment varaible */
		if (getenv("USER"))
			user_name = strdup(getenv("USER"));
		if (user_name == NULL)
			user_name = getusername();
		got_user = 1;
	}
       
	if(got_password == 0) {
		char *tmp_pass = getpass("Password: "******"Password not entered, exiting\n");
			exit(EX_USAGE);
		}
		strlcpy(mountpassword, tmp_pass, MOUNT_PASSWD_SIZE+1);
		got_password = 1;
	}
	/* FIXME launch daemon (handles dfs name resolution and credential change) 
	   remember to clear parms and overwrite password field before launching */
	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(EX_USAGE);
	}
	if(user_name)
		optlen += strlen(user_name) + 6;
	optlen += MAX_ADDRESS_LEN + 4;
	if(mountpassword)
		optlen += strlen(mountpassword) + 6;
mount_retry:
	SAFE_FREE(options);
	options_size = optlen + 10 + DOMAIN_SIZE;
	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");
		exit(EX_SYSERR);
	}

	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(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);
		}
	}

	strlcat(options,",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 / */
	}

	/* convert all '\\' to '/' in share portion so that /proc/mounts looks pretty */
	replace_char(dev_name, '\\', '/', strlen(share_name));

	if (!got_ip && addr) {
		strlcat(options, ",ip=", options_size);
		current_len = strnlen(options, options_size);
		optionstail = options + current_len;
		switch (addr->ai_addr->sa_family) {
		case AF_INET6:
			addr6 = (struct sockaddr_in6 *) addr->ai_addr;
			ipaddr = inet_ntop(AF_INET6, &addr6->sin6_addr, optionstail,
					   options_size - current_len);
			break;
		case AF_INET:
			addr4 = (struct sockaddr_in *) addr->ai_addr;
			ipaddr = inet_ntop(AF_INET, &addr4->sin_addr, optionstail,
					   options_size - current_len);
			break;
		}

		/* if the address looks bogus, try the next one */
		if (!ipaddr) {
			addr = addr->ai_next;
			if (addr)
				goto mount_retry;
			rc = EX_SYSERR;
			goto mount_exit;
		}
	}

	if(verboseflag)
		fprintf(stderr, "\nmount.cifs kernel mount options: %s", options);

	if (mountpassword) {
		/*
		 * Commas have to be doubled, or else they will
		 * look like the parameter separator
		 */
		if(retry == 0)
			check_for_comma(&mountpassword);
		strlcat(options,",pass="******",pass=********");
	}

	if (verboseflag)
		fprintf(stderr, "\n");

	if (!fakemnt && mount(dev_name, mountpoint, "cifs", flags, options)) {
		switch (errno) {
		case ECONNREFUSED:
		case EHOSTUNREACH:
			if (addr) {
				addr = addr->ai_next;
				if (addr)
					goto mount_retry;
			}
			break;
		case ENODEV:
			printf("mount error: cifs filesystem not supported by the system\n");
			break;
		case ENXIO:
			if(retry == 0) {
				retry = 1;
				if (uppercase_string(dev_name) &&
				    uppercase_string(share_name) &&
				    uppercase_string(prefixpath)) {
					printf("retrying with upper case share name\n");
					goto mount_retry;
				}
			}
		}
		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 = EX_FAIL;
		goto mount_exit;
	}

	if (nomtab)
		goto mount_exit;
	atexit(unlock_mtab);
	rc = lock_mtab();
	if (rc) {
		printf("cannot lock mtab");
		goto mount_exit;
	}
	pmntfile = setmntent(MOUNTED, "a+");
	if (!pmntfile) {
		printf("could not update mount table\n");
		unlock_mtab();
		rc = EX_FILEIO;
		goto mount_exit;
	}
	mountent.mnt_fsname = dev_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,",sync",220);
		if(mount_user) {
			if(getuid() != 0) {
				strlcat(mountent.mnt_opts,
					",user=", 220);
				strlcat(mountent.mnt_opts,
					mount_user, 220);
			}
		}
	}
	mountent.mnt_freq = 0;
	mountent.mnt_passno = 0;
	rc = addmntent(pmntfile,&mountent);
	endmntent(pmntfile);
	unlock_mtab();
	SAFE_FREE(mountent.mnt_opts);
	if (rc)
		rc = EX_FILEIO;
mount_exit:
	if(mountpassword) {
		int len = strlen(mountpassword);
		memset(mountpassword,0,len);
		SAFE_FREE(mountpassword);
	}

	if (addrhead)
		freeaddrinfo(addrhead);
	SAFE_FREE(options);
	SAFE_FREE(orgoptions);
	SAFE_FREE(resolved_path);
	SAFE_FREE(share_name);
	exit(rc);
}
コード例 #28
0
ファイル: tst-mntent.c プロジェクト: AdvancedC/glibc
int
main (int argc, char *argv[])
{
  int result = 0;
  struct mntent mef;
  struct mntent *mnt = &mef;
  FILE *fp;

  mef.mnt_fsname = strdupa ("/dev/hda1");
  mef.mnt_dir = strdupa ("/some dir");
  mef.mnt_type = strdupa ("ext2");
  mef.mnt_opts = strdupa ("defaults");
  mef.mnt_freq = 1;
  mef.mnt_passno = 2;

  if (hasmntopt (mnt, "defaults"))
    printf ("Found!\n");
  else
    {
      printf ("Didn't find it\n");
      result = 1;
    }

  fp = tmpfile ();
  if (fp == NULL)
    {
      printf ("Cannot open temporary file: %m\n");
      result = 1;
    }
  else
    {
      char buf[1024];

      /* Write the name entry.  */
      addmntent (fp, &mef);

      /* Prepare for reading.  */
      rewind (fp);

      /* First, read it raw.  */
      if (fgets (buf, sizeof (buf), fp) == NULL)
	{
	  printf ("Cannot read temporary file: %m");
	  result = 1;
	}
      else
	if (strcmp (buf, "/dev/hda1 /some\\040dir ext2 defaults 1 2\n") != 0)
	  {
	    puts ("Raw file data not correct");
	    result = 1;
	  }

      /* Prepare for reading, part II.  */
      rewind (fp);

      /* Now read it cooked.  */
      mnt = getmntent (fp);

      if (strcmp (mnt->mnt_fsname, "/dev/hda1") != 0
	  || strcmp (mnt->mnt_dir, "/some dir") != 0
	  || strcmp (mnt->mnt_type, "ext2") != 0
	  || strcmp (mnt->mnt_opts, "defaults") != 0
	  || mnt->mnt_freq != 1
	  || mnt->mnt_passno != 2)
	{
	  puts ("Error while reading written entry back in");
	  result = 1;
	}
    }

  return result;
}
コード例 #29
0
int
main(int argc, char *argv[])
{
    int fd;
    char* mount_point;
    struct mntent *mnt;
    FILE* mtab;
    FILE* new_mtab;

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

    if (geteuid() != 0) {
        fprintf(stderr, "smbumount must be installed suid root\n");
        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);
    }

    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;
    }

    return 0;
}
コード例 #30
0
ファイル: vbsfmount.c プロジェクト: CandyYao/VirtualBox-OSE
/** @todo Use defines for return values! */
int vbsfmount_complete(const char *host_name, const char *mount_point,
                       unsigned long flags, struct vbsf_mount_opts *opts)
{
    FILE *f, *m;
    char *buf;
    size_t size;
    struct mntent e;
    int rc = 0;

    m = open_memstream(&buf, &size);
    if (!m)
        return 1; /* Could not update mount table (failed to create memstream). */

    if (opts->uid)
        fprintf(m, "uid=%d,", opts->uid);
    if (opts->gid)
        fprintf(m, "gid=%d,", opts->gid);
    if (opts->ttl)
        fprintf(m, "ttl=%d,", opts->ttl);
    if (*opts->nls_name)
        fprintf(m, "iocharset=%s,", opts->nls_name);
    if (flags & MS_NOSUID)
        fprintf(m, "%s,", MNTOPT_NOSUID);
    if (flags & MS_RDONLY)
        fprintf(m, "%s,", MNTOPT_RO);
    else
        fprintf(m, "%s,", MNTOPT_RW);

    fclose(m);

    if (size > 0)
        buf[size - 1] = 0;
    else
        buf = "defaults";

    f = setmntent(MOUNTED, "a+");
    if (!f)
    {
        rc = 2; /* Could not open mount table for update. */
    }
    else
    {
        e.mnt_fsname = (char*)host_name;
        e.mnt_dir = (char*)mount_point;
        e.mnt_type = "vboxsf";
        e.mnt_opts = buf;
        e.mnt_freq = 0;
        e.mnt_passno = 0;

        if (addmntent(f, &e))
            rc = 3;  /* Could not add an entry to the mount table. */

        endmntent(f);
    }

    if (size > 0)
    {
        memset(buf, 0, size);
        free(buf);
    }

    return rc;
}