2000-02-18 03:38:33 +08:00
|
|
|
/* mount.cc
|
|
|
|
|
|
|
|
Copyright 1996, 1997, 1998, 1999 Cygnus Solutions.
|
|
|
|
|
|
|
|
This file is part of Cygwin.
|
|
|
|
|
|
|
|
This software is a copyrighted work licensed under the terms of the
|
|
|
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|
|
|
details. */
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/mount.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <mntent.h>
|
|
|
|
#include <windows.h>
|
|
|
|
#include <sys/cygwin.h>
|
2000-06-06 02:43:54 +08:00
|
|
|
#include <stdlib.h>
|
2000-02-18 03:38:33 +08:00
|
|
|
|
|
|
|
#ifdef errno
|
|
|
|
#undef errno
|
|
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
static void show_mounts (void);
|
2000-11-09 04:39:45 +08:00
|
|
|
static void show_cygdrive_info (void);
|
2000-02-18 03:38:33 +08:00
|
|
|
static void change_cygdrive_prefix (const char *new_prefix, int flags);
|
|
|
|
static int mount_already_exists (const char *posix_path, int flags);
|
|
|
|
|
|
|
|
// static short create_missing_dirs = FALSE;
|
|
|
|
static short force = FALSE;
|
|
|
|
|
|
|
|
static const char *progname;
|
|
|
|
|
2000-06-08 20:54:12 +08:00
|
|
|
static void
|
|
|
|
error (const char *path)
|
|
|
|
{
|
|
|
|
fprintf (stderr, "%s: %s: %s\n", progname, path,
|
|
|
|
(errno == EMFILE) ? "Too many mount entries" : strerror (errno));
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
2000-02-18 03:38:33 +08:00
|
|
|
/* FIXME: do_mount should also print a warning message if the dev arg
|
|
|
|
is a non-existent Win32 path. */
|
|
|
|
|
|
|
|
static void
|
|
|
|
do_mount (const char *dev, const char *where, int flags)
|
|
|
|
{
|
|
|
|
struct stat statbuf;
|
|
|
|
char win32_path[MAX_PATH];
|
|
|
|
int statres;
|
|
|
|
|
|
|
|
cygwin_conv_to_win32_path (where, win32_path);
|
|
|
|
|
|
|
|
statres = stat (win32_path, &statbuf);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (statres == -1)
|
|
|
|
{
|
|
|
|
/* FIXME: this'll fail if mount dir is missing any parent dirs */
|
|
|
|
if (create_missing_dirs == TRUE)
|
|
|
|
{
|
|
|
|
if (mkdir (where, 0755) == -1)
|
|
|
|
fprintf (stderr, "Warning: unable to create %s!\n", where);
|
|
|
|
else
|
|
|
|
statres = 0; /* Pretend stat succeeded if we could mkdir. */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (mount (dev, where, flags))
|
2000-06-08 20:54:12 +08:00
|
|
|
error (where);
|
2000-02-18 03:38:33 +08:00
|
|
|
|
|
|
|
if (statres == -1)
|
|
|
|
{
|
|
|
|
if (force == FALSE)
|
|
|
|
fprintf (stderr, "%s: warning - %s does not exist.\n", progname, where);
|
|
|
|
}
|
|
|
|
else if (!(statbuf.st_mode & S_IFDIR))
|
|
|
|
{
|
|
|
|
if (force == FALSE)
|
2000-07-14 05:49:36 +08:00
|
|
|
fprintf (stderr, "%s: warning: %s is not a directory.\n", progname, where);
|
2000-10-28 13:00:00 +08:00
|
|
|
}
|
2000-02-18 03:38:33 +08:00
|
|
|
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
usage (void)
|
|
|
|
{
|
|
|
|
fprintf (stderr, "usage %s [-bfstux] <win32path> <posixpath>
|
|
|
|
-b text files are equivalent to binary files (newline = \\n)
|
|
|
|
-f force mount, don't warn about missing mount point directories
|
|
|
|
-s add mount point to system-wide registry location
|
|
|
|
-t text files get \\r\\n line endings (default)
|
|
|
|
-u add mount point to user registry location (default)
|
|
|
|
-x treat all files under mount point as executables
|
|
|
|
|
|
|
|
[-bs] --change-cygdrive-prefix <posixpath>
|
|
|
|
change the cygdrive path prefix to <posixpath>
|
2000-07-29 06:34:24 +08:00
|
|
|
--show-cygdrive-prefixes
|
|
|
|
show user and/or system cygdrive path prefixes
|
2000-02-18 03:38:33 +08:00
|
|
|
--import-old-mounts
|
|
|
|
copy old registry mount table mounts into the current mount areas
|
|
|
|
", progname);
|
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
main (int argc, const char **argv)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int flags = 0;
|
|
|
|
|
|
|
|
progname = argv[0];
|
|
|
|
|
|
|
|
if (argc == 1)
|
|
|
|
{
|
|
|
|
show_mounts ();
|
|
|
|
exit (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 1; i < argc; ++i)
|
|
|
|
{
|
2000-04-27 11:44:23 +08:00
|
|
|
if (argv[i][0] != '-')
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (strcmp (argv[i], "--change-cygdrive-prefix") == 0)
|
|
|
|
{
|
|
|
|
if ((i + 2) != argc)
|
|
|
|
usage ();
|
|
|
|
|
|
|
|
change_cygdrive_prefix (argv[i+1], flags);
|
|
|
|
}
|
|
|
|
else if (strcmp (argv[i], "--import-old-mounts") == 0)
|
|
|
|
{
|
|
|
|
if ((i + 1) != argc)
|
|
|
|
usage ();
|
|
|
|
|
|
|
|
cygwin_internal (CW_READ_V1_MOUNT_TABLES);
|
|
|
|
exit (0);
|
|
|
|
}
|
2000-07-29 06:34:24 +08:00
|
|
|
else if (strcmp (argv[i], "--show-cygdrive-prefixes") == 0)
|
|
|
|
{
|
|
|
|
if ((i + 1) != argc)
|
|
|
|
usage ();
|
|
|
|
|
2000-11-09 04:39:45 +08:00
|
|
|
show_cygdrive_info ();
|
2000-07-29 06:34:24 +08:00
|
|
|
}
|
2000-04-27 11:44:23 +08:00
|
|
|
else if (strcmp (argv[i], "-b") == 0)
|
|
|
|
flags |= MOUNT_BINARY;
|
|
|
|
else if (strcmp (argv[i], "-t") == 0)
|
|
|
|
flags &= ~MOUNT_BINARY;
|
|
|
|
else if (strcmp (argv[i], "-X") == 0)
|
|
|
|
flags |= MOUNT_CYGWIN_EXEC;
|
2000-02-18 03:38:33 +08:00
|
|
|
#if 0
|
2000-04-27 11:44:23 +08:00
|
|
|
else if (strcmp (argv[i], "-x") == 0)
|
|
|
|
create_missing_dirs = TRUE;
|
2000-02-18 03:38:33 +08:00
|
|
|
#endif
|
2000-04-27 11:44:23 +08:00
|
|
|
else if (strcmp (argv[i], "-s") == 0)
|
|
|
|
flags |= MOUNT_SYSTEM;
|
|
|
|
else if (strcmp (argv[i], "-u") == 0)
|
|
|
|
flags &= ~MOUNT_SYSTEM;
|
|
|
|
else if (strcmp (argv[i], "-x") == 0)
|
|
|
|
flags |= MOUNT_EXEC;
|
|
|
|
else if (strcmp (argv[i], "-f") == 0)
|
|
|
|
force = TRUE;
|
|
|
|
else
|
|
|
|
usage ();
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
2000-10-28 13:00:00 +08:00
|
|
|
|
2000-02-18 03:38:33 +08:00
|
|
|
if ((i + 2) != argc)
|
|
|
|
usage ();
|
|
|
|
|
|
|
|
if ((force == FALSE) && (mount_already_exists (argv[i + 1], flags)))
|
|
|
|
{
|
|
|
|
errno = EBUSY;
|
2000-06-08 20:54:12 +08:00
|
|
|
error (argv[i + 1]);
|
2000-02-18 03:38:33 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
do_mount (argv[i], argv[i + 1], flags);
|
|
|
|
|
|
|
|
/* NOTREACHED */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
show_mounts (void)
|
|
|
|
{
|
|
|
|
FILE *m = setmntent ("/-not-used-", "r");
|
|
|
|
struct mntent *p;
|
|
|
|
const char *format = "%-18s %-18s %-11s %s\n";
|
|
|
|
|
|
|
|
printf (format, "Device", "Directory", "Type", "Flags");
|
|
|
|
while ((p = getmntent (m)) != NULL)
|
|
|
|
{
|
|
|
|
printf (format,
|
|
|
|
p->mnt_fsname,
|
|
|
|
p->mnt_dir,
|
|
|
|
p->mnt_type,
|
|
|
|
p->mnt_opts);
|
|
|
|
}
|
|
|
|
endmntent (m);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return 1 if mountpoint from the same registry area is already in
|
|
|
|
mount table. Otherwise return 0. */
|
|
|
|
static int
|
|
|
|
mount_already_exists (const char *posix_path, int flags)
|
|
|
|
{
|
|
|
|
int found_matching = 0;
|
|
|
|
|
|
|
|
FILE *m = setmntent ("/-not-used-", "r");
|
|
|
|
struct mntent *p;
|
|
|
|
|
|
|
|
while ((p = getmntent (m)) != NULL)
|
|
|
|
{
|
|
|
|
/* if the paths match, and they're both the same type of mount. */
|
|
|
|
if (strcmp (p->mnt_dir, posix_path) == 0)
|
|
|
|
{
|
2000-07-14 05:49:36 +08:00
|
|
|
if (p->mnt_type[0] == 'u')
|
2000-02-18 03:38:33 +08:00
|
|
|
{
|
2000-07-14 05:49:36 +08:00
|
|
|
if (!(flags & MOUNT_SYSTEM)) /* both current_user */
|
|
|
|
found_matching = 1;
|
|
|
|
else
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: warning: system mount point of '%s' "
|
|
|
|
"will always be masked by user mount.\n",
|
|
|
|
progname, posix_path);
|
2000-02-18 03:38:33 +08:00
|
|
|
break;
|
2000-07-14 05:49:36 +08:00
|
|
|
}
|
|
|
|
else if (p->mnt_type[0] == 's')
|
2000-02-18 03:38:33 +08:00
|
|
|
{
|
2000-07-14 05:49:36 +08:00
|
|
|
if (flags & MOUNT_SYSTEM) /* both system */
|
|
|
|
found_matching = 1;
|
|
|
|
else
|
|
|
|
fprintf (stderr,
|
|
|
|
"%s: warning: user mount point of '%s' "
|
|
|
|
"masks system mount.\n",
|
|
|
|
progname, posix_path);
|
2000-02-18 03:38:33 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2000-07-14 05:49:36 +08:00
|
|
|
fprintf (stderr, "%s: warning: couldn't determine mount type.\n", progname);
|
2000-02-18 03:38:33 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
endmntent (m);
|
|
|
|
|
|
|
|
return found_matching;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* change_cygdrive_prefix: Change the cygdrive prefix */
|
|
|
|
static void
|
|
|
|
change_cygdrive_prefix (const char *new_prefix, int flags)
|
|
|
|
{
|
|
|
|
flags |= MOUNT_AUTO;
|
|
|
|
|
|
|
|
if (mount (NULL, new_prefix, flags))
|
2000-06-08 20:54:12 +08:00
|
|
|
error (new_prefix);
|
2000-10-28 13:00:00 +08:00
|
|
|
|
2000-02-18 03:38:33 +08:00
|
|
|
exit (0);
|
|
|
|
}
|
2000-07-29 06:34:24 +08:00
|
|
|
|
2000-11-09 04:39:45 +08:00
|
|
|
/* show_cygdrive_info: Show the user and/or cygdrive info, i.e., prefixes and
|
|
|
|
flags.*/
|
2000-07-29 06:34:24 +08:00
|
|
|
static void
|
2000-11-09 04:39:45 +08:00
|
|
|
show_cygdrive_info ()
|
2000-07-29 06:34:24 +08:00
|
|
|
{
|
2000-11-09 04:39:45 +08:00
|
|
|
/* Get the cygdrive info */
|
2000-07-29 06:34:24 +08:00
|
|
|
char user[MAX_PATH];
|
|
|
|
char system[MAX_PATH];
|
2000-11-09 04:39:45 +08:00
|
|
|
char user_flags[MAX_PATH];
|
|
|
|
char system_flags[MAX_PATH];
|
|
|
|
cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags,
|
|
|
|
system_flags);
|
2000-07-29 06:34:24 +08:00
|
|
|
|
|
|
|
/* Display the user and system cygdrive path prefixes, if necessary
|
|
|
|
(ie, not empty) */
|
2000-11-09 04:39:45 +08:00
|
|
|
const char *format = "%-18s %-11s %s\n";
|
|
|
|
printf (format, "Prefix", "Type", "Flags");
|
2000-07-29 06:34:24 +08:00
|
|
|
if (strlen (user) > 0)
|
2000-11-09 04:39:45 +08:00
|
|
|
printf (format, user, "user", user_flags);
|
2000-07-29 06:34:24 +08:00
|
|
|
if (strlen (system) > 0)
|
2000-11-09 04:39:45 +08:00
|
|
|
printf (format, system, "system", system_flags);
|
2000-07-29 06:34:24 +08:00
|
|
|
|
|
|
|
exit (0);
|
|
|
|
}
|