mount.vboxsf.c revision c58f1213e628a545081c70e26c6b67a841cff880
/** @file
* vboxsf -- VirtualBox Guest Additions for Linux: mount(8) helper
*
* Parses options provided by mount (or user directly)
* Packs them into struct vbsfmount and passes to mount(2)
* Optionally adds entries to mtab
*/
/*
* Copyright (C) 2006-2012 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
/* #define DEBUG */
#define DBG if (0)
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <getopt.h>
#include <mntent.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <mntent.h>
#include <limits.h>
#include <iconv.h>
#include "vbsfmount.h"
/* Compile-time assertion. If a == 0, we get two identical switch cases, which is not
allowed. */
#define CT_ASSERT(a) \
do { \
switch(0) { case 0: case (a): ; } \
} while (0)
static void PANIC_ATTR
{
}
static void PANIC_ATTR
{
int errno_code = errno;
}
static int
{
char *endptr;
{
panic_err("could not convert %.*s to integer, result = %d",
}
return (int)val;
}
static void
{
const char *next = s;
typedef enum handler_opt
{
HORW,
HORO,
} handler_opt;
struct
{
const char *name;
int has_arg;
const char *desc;
} handlers[]
=
{
{"dev", HODEV, 0, 0 },
{"nosuid", HONOSUID, 0, 0 },
{"suid", HOSUID, 0, 0 },
{"remount", HOREMOUNT, 0, 0 },
{"noauto", HONOAUTO, 0, 0 },
{"_netdev", HONIGNORE, 0, 0 },
}, *handler;
while (next)
{
const char *val;
s = next;
if (!next)
{
}
else
{
next += 1;
if (!*next)
next = 0;
}
val_len = 0;
{
if (s[key_len] == '=')
{
{
}
break;
}
}
{
size_t j;
;
{
{
{
panic("%.*s requires an argument (i.e. %.*s=<arg>)\n",
}
}
{
case HORW:
break;
case HORO:
break;
case HONOEXEC:
break;
case HOEXEC:
break;
case HONODEV:
break;
case HODEV:
break;
case HONOSUID:
break;
case HOSUID:
break;
case HOREMOUNT:
break;
case HOUID:
/** @todo convert string to id. */
break;
case HOGID:
/** @todo convert string to id. */
break;
case HOTTL:
break;
case HODMODE:
break;
case HOFMODE:
break;
case HOUMASK:
break;
case HODMASK:
break;
case HOFMASK:
break;
case HOIOCHARSET:
{
panic("iocharset name too long\n");
}
break;
case HOCONVERTCP:
{
panic_err("could not allocate memory");
}
break;
case HONOAUTO:
case HONIGNORE:
break;
}
break;
}
continue;
}
{
{
}
}
}
}
static void
{
char *i = host_name;
{
panic_err("could not convert share name, iconv_open `%s' failed",
}
while (ib)
{
if (c == (size_t) -1)
{
panic_err("could not convert share name(%s) at %d",
}
}
*o = 0;
}
/**
* Print out a usage message and exit.
*
* @param name The name of the application
*/
{
printf("Usage: %s [OPTIONS] NAME MOUNTPOINT\n"
"Mount the VirtualBox shared folder NAME from the host system to MOUNTPOINT.\n"
"\n"
" -w mount the shared folder writable (the default)\n"
" -r mount the shared folder read-only\n"
" -n do not create an mtab entry\n"
" -o OPTION[,OPTION...] use the mount options specified\n"
"\n", name);
printf("Available mount options are:\n"
" rw mount writable (the default)\n"
" ro mount read only\n"
" uid=UID set the default file owner user id to UID\n"
" gid=GID set the default file owner group id to GID\n"
" ttl=TTL set the \"time to live\" to TID for the dentry\n");
printf(" dmode=MODE override the mode of all directories to (octal) MODE\n"
" fmode=MODE override the mode of all regular files to (octal) MODE\n"
" umask=UMASK set the umask to (octal) UMASK\n");
printf(" dmask=UMASK set the umask applied to directories only\n"
" fmask=UMASK set the umask applied to regular files only\n"
" iocharset CHARSET use the character set CHARSET for I/O operations\n"
" (default set is utf8)\n"
" convertcp CHARSET convert the folder name from CHARSET to utf8\n"
"\n");
printf("Less common used options:\n"
" noexec,exec,nodev,dev,nosuid,suid\n");
exit(1);
}
int
{
int c;
int err;
int nomtab = 0;
char *host_name;
char *mount_point;
struct vbsf_mount_info_new mntinf;
struct vbsf_mount_opts opts =
{
0, /* uid */
0, /* gid */
0, /* ttl */
~0U, /* dmode */
~0U, /* fmode*/
0, /* dmask */
0, /* fmask */
0, /* ronly */
0, /* noexec */
0, /* nodev */
0, /* nosuid */
0, /* remount */
"\0", /* nls_name */
NULL, /* convertcp */
};
if (getuid())
panic("Only root can mount shared folders from the host.\n");
if (!argv[0])
argv[0] = "mount.vboxsf";
/* Compile-time assertions */
{
switch (c)
{
default:
case '?':
case 'h':
case 'r':
break;
case 'w':
case 'o':
break;
case 'n':
nomtab = 1;
break;
}
}
else
{
panic("host name is too big\n");
}
flags |= MS_REMOUNT;
/*
* options you also would have to adjust VBoxServiceAutoMount.cpp
* to keep this code here slick without having VbglR3.
*/
{
/* Sometimes the mount utility messes up the share name. Try to
* un-mangle it again. */
char szCWD[4096];
{
++cchCWD;
/* We checked before that we have enough space */
}
}
{
/* New mount tool with old vboxsf module? Try again using the old
* vbsf_mount_info_old structure. */
struct vbsf_mount_info_old mntinf_old;
}
if (err)
if (!nomtab)
{
switch (err)
{
case 0: /* Success. */
break;
case 1:
break;
case 2:
break;
case 3:
/* panic_err("%s: Could not add an entry to the mount table.", argv[0]); */
break;
default:
break;
}
}
}