]>
Commit | Line | Data |
---|---|---|
1fd5e000 CF |
1 | /* mount.cc |
2 | ||
df0f949c | 3 | Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, |
61522196 | 4 | 2007, 2008, 2009, 2010, 2011, 2013 Red Hat, Inc. |
1fd5e000 CF |
5 | |
6 | This file is part of Cygwin. | |
7 | ||
8 | This software is a copyrighted work licensed under the terms of the | |
9 | Cygwin license. Please consult the file "CYGWIN_LICENSE" for | |
10 | details. */ | |
11 | ||
12 | #include <stdio.h> | |
13 | #include <sys/mount.h> | |
14 | #include <sys/stat.h> | |
15 | #include <mntent.h> | |
16 | #include <windows.h> | |
17 | #include <sys/cygwin.h> | |
92b499ac | 18 | #include <cygwin/version.h> |
b6e259b1 | 19 | #include <stdlib.h> |
1e497ebd | 20 | #include <unistd.h> |
be61cf4d | 21 | #include <getopt.h> |
035df9ef | 22 | #include <dirent.h> |
1e497ebd | 23 | #include "path.h" |
1fd5e000 | 24 | |
1fd5e000 CF |
25 | #include <errno.h> |
26 | ||
56d81795 CV |
27 | #define NT_MAX_PATH 32768 |
28 | ||
48897dfe CF |
29 | #define EXEC_FLAGS (MOUNT_EXEC | MOUNT_NOTEXEC | MOUNT_CYGWIN_EXEC) |
30 | ||
56d81795 | 31 | static void mount_entries (void); |
1fd5e000 | 32 | static void show_mounts (void); |
4c35f9f0 | 33 | static void show_cygdrive_info (void); |
1fd5e000 CF |
34 | static void change_cygdrive_prefix (const char *new_prefix, int flags); |
35 | static int mount_already_exists (const char *posix_path, int flags); | |
36 | ||
37 | // static short create_missing_dirs = FALSE; | |
1e497ebd | 38 | static bool force = false; |
1fd5e000 CF |
39 | |
40 | static const char *progname; | |
41 | ||
9500a3db CV |
42 | static void |
43 | error (const char *path) | |
44 | { | |
45 | fprintf (stderr, "%s: %s: %s\n", progname, path, | |
46 | (errno == EMFILE) ? "Too many mount entries" : strerror (errno)); | |
47 | exit (1); | |
48 | } | |
49 | ||
1fd5e000 CF |
50 | /* FIXME: do_mount should also print a warning message if the dev arg |
51 | is a non-existent Win32 path. */ | |
52 | ||
53 | static void | |
54 | do_mount (const char *dev, const char *where, int flags) | |
55 | { | |
56 | struct stat statbuf; | |
1fd5e000 CF |
57 | int statres; |
58 | ||
c2b88623 | 59 | statres = stat (where, &statbuf); |
1fd5e000 CF |
60 | |
61 | #if 0 | |
62 | if (statres == -1) | |
63 | { | |
64 | /* FIXME: this'll fail if mount dir is missing any parent dirs */ | |
65 | if (create_missing_dirs == TRUE) | |
66 | { | |
67 | if (mkdir (where, 0755) == -1) | |
68 | fprintf (stderr, "Warning: unable to create %s!\n", where); | |
69 | else | |
70 | statres = 0; /* Pretend stat succeeded if we could mkdir. */ | |
71 | } | |
72 | } | |
73 | #endif | |
74 | ||
1fd5e000 CF |
75 | if (statres == -1) |
76 | { | |
48897dfe | 77 | if (!force) |
1fd5e000 CF |
78 | fprintf (stderr, "%s: warning - %s does not exist.\n", progname, where); |
79 | } | |
80 | else if (!(statbuf.st_mode & S_IFDIR)) | |
81 | { | |
48897dfe | 82 | if (!force) |
92b499ac CV |
83 | fprintf (stderr, "%s: warning: %s is not a directory.\n", |
84 | progname, where); | |
eedc36cb | 85 | } |
1fd5e000 | 86 | |
68a178b3 | 87 | if (!force && !(flags & (EXEC_FLAGS | MOUNT_BIND)) && strlen (dev)) |
48897dfe CF |
88 | { |
89 | char devtmp[1 + 2 * strlen (dev)]; | |
90 | strcpy (devtmp, dev); | |
91 | char c = strchr (devtmp, '\0')[-1]; | |
92 | if (c == '/' || c == '\\') | |
93 | strcat (devtmp, "."); | |
94 | /* Use a curious property of Windows which allows the use of \.. even | |
4bfc614b | 95 | on non-directory paths. */ |
48897dfe CF |
96 | for (const char *p = dev; (p = strpbrk (p, "/\\")); p++) |
97 | strcat (devtmp, "\\.."); | |
98 | strcat (devtmp, "\\"); | |
99 | if (GetDriveType (devtmp) == DRIVE_REMOTE) | |
100 | { | |
92b499ac CV |
101 | fprintf (stderr, |
102 | "%s: defaulting to 'notexec' mount option for speed since native path\n" | |
103 | "%*creferences a remote share. Use '-f' option to override.\n", | |
61522196 | 104 | progname, (int) strlen(progname) + 2, ' '); |
48897dfe CF |
105 | flags |= MOUNT_NOTEXEC; |
106 | } | |
107 | } | |
108 | ||
109 | if (mount (dev, where, flags)) | |
110 | error (where); | |
1fd5e000 CF |
111 | } |
112 | ||
1e497ebd CV |
113 | static void |
114 | from_fstab (bool user) | |
115 | { | |
116 | char path[PATH_MAX]; | |
117 | char buf[65536]; | |
118 | mnt_t *m = mount_table + max_mount_entry; | |
119 | ||
120 | strcpy (path, "/etc/fstab"); | |
121 | if (user) | |
122 | { | |
123 | strcat (path, ".d/"); | |
124 | strcat (path, getlogin ()); | |
125 | } | |
126 | FILE *fh = fopen (path, "rt"); | |
127 | if (!fh) | |
128 | return; | |
129 | while (fgets (buf, 65536, fh)) | |
130 | { | |
131 | char *c = strrchr (buf, '\n'); | |
5578c337 | 132 | if (c) |
1e497ebd CV |
133 | *c = '\0'; |
134 | if (from_fstab_line (m, buf, user)) | |
135 | ++m; | |
136 | } | |
137 | max_mount_entry = m - mount_table; | |
138 | fclose (fh); | |
139 | } | |
140 | ||
141 | static void | |
142 | do_mount_from_fstab (const char *where) | |
143 | { | |
144 | force = true; | |
145 | /* Read fstab entries. */ | |
146 | from_fstab (false); | |
147 | from_fstab (true); | |
148 | /* Loop through fstab entries and see if it matches `where'. If `where' | |
149 | is NULL, all entries match. */ | |
150 | bool exists = false; | |
151 | for (mnt_t *m = mount_table; m - mount_table < max_mount_entry; ++m) | |
f380ca58 | 152 | if (!where || !strcmp (where, m->posix)) |
1e497ebd | 153 | { |
f380ca58 CV |
154 | if (m->flags & MOUNT_CYGDRIVE) |
155 | { | |
156 | /* Get the cygdrive info */ | |
157 | char user[MAX_PATH]; | |
158 | char system[MAX_PATH]; | |
159 | char user_flags[MAX_PATH]; | |
160 | char system_flags[MAX_PATH]; | |
161 | ||
162 | exists = true; | |
163 | cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, | |
164 | system_flags); | |
165 | if ((*user && strcmp (user, m->posix) != 0) | |
166 | || (*system && strcmp (system, m->posix) != 0)) | |
167 | if (mount (NULL, m->posix, m->flags)) | |
168 | error (m->posix); | |
169 | } | |
170 | else | |
171 | { | |
172 | exists = true; | |
173 | /* Compare with existing mount table. If the entry doesn't exist, | |
174 | mount it. */ | |
175 | FILE *mt = setmntent ("/-not-used-", "r"); | |
176 | struct mntent *p; | |
177 | ||
178 | while ((p = getmntent (mt)) != NULL) | |
179 | if (!strcmp (m->posix, p->mnt_dir)) | |
180 | break; | |
181 | if (!p) | |
182 | do_mount (m->native, m->posix, m->flags); | |
183 | endmntent (mt); | |
184 | if (where) | |
185 | break; | |
186 | } | |
1e497ebd CV |
187 | } |
188 | if (!exists && where) | |
189 | fprintf (stderr, | |
190 | "%s: can't find %s in /etc/fstab or in /etc/fstab.d/$USER\n", | |
191 | progname, where); | |
192 | } | |
193 | ||
c49fa762 | 194 | static struct option longopts[] = |
be61cf4d | 195 | { |
1e497ebd | 196 | {"all", no_argument, NULL, 'a'}, |
be61cf4d | 197 | {"change-cygdrive-prefix", no_argument, NULL, 'c'}, |
8704ad9d CF |
198 | {"force", no_argument, NULL, 'f'}, |
199 | {"help", no_argument, NULL, 'h' }, | |
56d81795 | 200 | {"mount-entries", no_argument, NULL, 'm'}, |
bb002a49 | 201 | {"options", required_argument, NULL, 'o'}, |
8704ad9d | 202 | {"show-cygdrive-prefix", no_argument, NULL, 'p'}, |
92b499ac | 203 | {"version", no_argument, NULL, 'V'}, |
be61cf4d CF |
204 | {NULL, 0, NULL, 0} |
205 | }; | |
206 | ||
92b499ac | 207 | static char opts[] = "acfhmpVo:"; |
56d81795 | 208 | |
1fd5e000 | 209 | static void |
8704ad9d | 210 | usage (FILE *where = stderr) |
1fd5e000 | 211 | { |
a82a8dcb CV |
212 | char *options; |
213 | ||
92b499ac CV |
214 | fprintf (where, "Usage: %1$s [OPTION] [<win32path> <posixpath>]\n\ |
215 | %1$s -a\n\ | |
216 | %1$s <posixpath>\n\ | |
217 | \n\ | |
aa275fe0 JDF |
218 | Display information about mounted filesystems, or mount a filesystem\n\ |
219 | \n\ | |
1e497ebd | 220 | -a, --all mount all filesystems mentioned in fstab\n\ |
be61cf4d CF |
221 | -c, --change-cygdrive-prefix change the cygdrive path prefix to <posixpath>\n\ |
222 | -f, --force force mount, don't warn about missing mount\n\ | |
9f425256 | 223 | point directories\n\ |
8704ad9d | 224 | -h, --help output usage information and exit\n\ |
56d81795 CV |
225 | -m, --mount-entries write fstab entries to replicate mount points\n\ |
226 | and cygdrive prefixes\n\ | |
08604f02 | 227 | -o, --options X[,X...] specify mount options\n\ |
be61cf4d | 228 | -p, --show-cygdrive-prefix show user and/or system cygdrive path prefix\n\ |
92b499ac CV |
229 | -V, --version output version information and exit\n\n", |
230 | progname); | |
a82a8dcb CV |
231 | if (!cygwin_internal (CW_LST_MNT_OPTS, &options)) |
232 | fprintf (where, "Valid options are: %s\n\n", options); | |
8704ad9d CF |
233 | exit (where == stderr ? 1 : 0); |
234 | } | |
235 | ||
236 | static void | |
237 | print_version () | |
238 | { | |
92b499ac | 239 | printf ("mount (cygwin) %d.%d.%d\n" |
1b23b30b CF |
240 | "Mount filesystem utility\n" |
241 | "Copyright (C) 1996 - %s Red Hat, Inc.\n" | |
242 | "This is free software; see the source for copying conditions. There is NO\n" | |
92b499ac | 243 | "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n", |
1b23b30b CF |
244 | CYGWIN_VERSION_DLL_MAJOR / 1000, |
245 | CYGWIN_VERSION_DLL_MAJOR % 1000, | |
246 | CYGWIN_VERSION_DLL_MINOR, | |
247 | strrchr (__DATE__, ' ') + 1); | |
1fd5e000 CF |
248 | } |
249 | ||
08604f02 CF |
250 | static char * |
251 | concat3 (char *a, const char *b, const char *c) | |
252 | { | |
253 | size_t totlen = strlen (a) + strlen (b) + strlen (c) + 1; | |
254 | a = (char *) realloc (a, totlen); | |
255 | return strcat (strcat (a, b), c); | |
256 | } | |
257 | ||
1fd5e000 | 258 | int |
be61cf4d | 259 | main (int argc, char **argv) |
1fd5e000 CF |
260 | { |
261 | int i; | |
b050246c | 262 | int flags = MOUNT_BINARY; |
08604f02 | 263 | char *options = strdup (""); |
be61cf4d CF |
264 | enum do_what |
265 | { | |
266 | nada, | |
267 | saw_change_cygdrive_prefix, | |
bee722a5 | 268 | saw_show_cygdrive_prefix, |
1e497ebd CV |
269 | saw_mount_commands, |
270 | saw_mount_all, | |
be61cf4d | 271 | } do_what = nada; |
1fd5e000 | 272 | |
92b499ac | 273 | progname = program_invocation_short_name; |
1fd5e000 CF |
274 | |
275 | if (argc == 1) | |
276 | { | |
277 | show_mounts (); | |
278 | exit (0); | |
279 | } | |
280 | ||
be61cf4d CF |
281 | while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) |
282 | switch (i) | |
283 | { | |
1e497ebd CV |
284 | case 'a': |
285 | if (do_what == nada) | |
286 | do_what = saw_mount_all; | |
287 | else | |
288 | usage (); | |
289 | break; | |
9f425256 | 290 | case 'c': |
be61cf4d CF |
291 | if (do_what == nada) |
292 | do_what = saw_change_cygdrive_prefix; | |
293 | else | |
294 | usage (); | |
295 | break; | |
296 | case 'f': | |
1e497ebd | 297 | force = true; |
be61cf4d | 298 | break; |
8704ad9d CF |
299 | case 'h': |
300 | usage (stdout); | |
301 | break; | |
8704ad9d CF |
302 | case 'm': |
303 | if (do_what == nada) | |
304 | do_what = saw_mount_commands; | |
305 | else | |
306 | usage (); | |
307 | break; | |
08604f02 | 308 | case 'o': |
1e497ebd CV |
309 | if (do_what == saw_mount_all) |
310 | usage (); | |
311 | else if (*options) | |
08604f02 CF |
312 | options = concat3 (options, ",", optarg); |
313 | else | |
314 | options = strdup (optarg); | |
315 | break; | |
be61cf4d CF |
316 | case 'p': |
317 | if (do_what == nada) | |
318 | do_what = saw_show_cygdrive_prefix; | |
319 | else | |
320 | usage (); | |
321 | break; | |
92b499ac | 322 | case 'V': |
8704ad9d CF |
323 | print_version (); |
324 | return 0; | |
be61cf4d | 325 | break; |
be61cf4d | 326 | default: |
92b499ac CV |
327 | fprintf (stderr, "Try `%s --help' for more information.\n", progname); |
328 | return 1; | |
be61cf4d | 329 | } |
eedc36cb | 330 | |
a82a8dcb | 331 | if (cygwin_internal (CW_CVT_MNT_OPTS, &options, &flags)) |
08604f02 | 332 | { |
08604f02 CF |
333 | fprintf (stderr, "%s: invalid option - '%s'\n", progname, options); |
334 | exit (1); | |
08604f02 CF |
335 | } |
336 | ||
48897dfe CF |
337 | if (flags & MOUNT_NOTEXEC && flags & (MOUNT_EXEC | MOUNT_CYGWIN_EXEC)) |
338 | { | |
92b499ac CV |
339 | fprintf (stderr, "%s: invalid combination of executable options\n", |
340 | progname); | |
48897dfe CF |
341 | exit (1); |
342 | } | |
343 | ||
e7fd6e57 CF |
344 | cygwin_internal (CW_SET_DOS_FILE_WARNING, false); |
345 | ||
be61cf4d CF |
346 | argc--; |
347 | switch (do_what) | |
1fd5e000 | 348 | { |
be61cf4d CF |
349 | case saw_change_cygdrive_prefix: |
350 | if (optind != argc) | |
351 | usage (); | |
f7483b41 | 352 | change_cygdrive_prefix (argv[optind], flags); |
be61cf4d | 353 | break; |
be61cf4d CF |
354 | case saw_show_cygdrive_prefix: |
355 | if (optind <= argc) | |
356 | usage (); | |
357 | show_cygdrive_info (); | |
358 | break; | |
bee722a5 CF |
359 | case saw_mount_commands: |
360 | if (optind <= argc) | |
361 | usage (); | |
56d81795 | 362 | mount_entries (); |
bee722a5 | 363 | break; |
1e497ebd CV |
364 | case saw_mount_all: |
365 | if (optind <= argc) | |
1b23b30b | 366 | usage (); |
1e497ebd CV |
367 | do_mount_from_fstab (NULL); |
368 | break; | |
be61cf4d | 369 | default: |
1e497ebd CV |
370 | if (optind == argc) |
371 | do_mount_from_fstab (argv[optind]); | |
372 | else if (optind != (argc - 1)) | |
be61cf4d | 373 | { |
1e497ebd | 374 | fprintf (stderr, "%s: too many arguments\n", progname); |
be61cf4d CF |
375 | usage (); |
376 | } | |
1e497ebd | 377 | else if (force || !mount_already_exists (argv[optind + 1], flags)) |
f7483b41 | 378 | do_mount (argv[optind], argv[optind + 1], flags); |
be61cf4d CF |
379 | else |
380 | { | |
381 | errno = EBUSY; | |
382 | error (argv[optind + 1]); | |
383 | } | |
1fd5e000 | 384 | } |
1fd5e000 CF |
385 | |
386 | /* NOTREACHED */ | |
387 | return 0; | |
388 | } | |
389 | ||
56d81795 CV |
390 | static char * |
391 | convert_spaces (char *tgt, const char *src) | |
392 | { | |
393 | char *tp, *spacep; | |
394 | const char *sp; | |
395 | ||
396 | tp = tgt; | |
397 | for (sp = src; (spacep = strchr (sp, ' ')); sp = spacep + 1) | |
398 | { | |
399 | tp = stpncpy (tp, sp, spacep - sp); | |
400 | tp = stpcpy (tp, "\\040"); | |
401 | } | |
402 | stpcpy (tp, sp); | |
403 | return tgt; | |
404 | } | |
405 | ||
bee722a5 | 406 | static void |
56d81795 | 407 | mount_entries (void) |
bee722a5 CF |
408 | { |
409 | FILE *m = setmntent ("/-not-used-", "r"); | |
410 | struct mntent *p; | |
56d81795 CV |
411 | const char *format_mnt = "%s %s %s %s 0 0\n"; |
412 | const char *format_cyg = "none %s cygdrive %s 0 0\n"; | |
bee722a5 | 413 | |
56d81795 | 414 | // write fstab entries for normal mount points |
e48feef9 | 415 | while ((p = getmntent (m)) != NULL) |
68a178b3 | 416 | // Only list non-cygdrives and non-automounts |
e9517437 | 417 | if (!strstr (p->mnt_opts, ",noumount") && !strstr (p->mnt_opts, ",auto")) |
e48feef9 | 418 | { |
56d81795 | 419 | char fsname[NT_MAX_PATH], dirname[NT_MAX_PATH]; |
68a178b3 CV |
420 | /* Drop the "bind" option since it can't be reverted. */ |
421 | char *c = strstr (p->mnt_opts, ",bind"); | |
422 | if (c) | |
423 | memmove (c, c + 5, strlen (c + 5) + 1); | |
56d81795 CV |
424 | printf (format_mnt, convert_spaces (fsname, p->mnt_fsname), |
425 | convert_spaces (dirname, p->mnt_dir), | |
426 | p->mnt_type, p->mnt_opts); | |
e48feef9 | 427 | } |
bee722a5 CF |
428 | endmntent (m); |
429 | ||
56d81795 CV |
430 | // write fstab entry for cygdrive prefix |
431 | m = setmntent ("/-not-used-", "r"); | |
432 | while ((p = getmntent (m)) != NULL) | |
e48feef9 | 433 | { |
56d81795 CV |
434 | char *noumount; |
435 | if ((noumount = strstr (p->mnt_opts, ",noumount"))) | |
1b23b30b | 436 | { |
56d81795 CV |
437 | char dirname[NT_MAX_PATH]; |
438 | char opts[strlen (p->mnt_opts) + 1]; | |
439 | ||
440 | convert_spaces (dirname, p->mnt_dir); | |
8262e642 | 441 | // remove trailing slash |
56d81795 | 442 | char *ls = strrchr (dirname, '/'); |
8262e642 CV |
443 | if (ls) |
444 | { | |
445 | // last slash == leading slash? cygdrive prefix == "/" | |
446 | if (ls == dirname) | |
447 | ++ls; | |
448 | *ls = '\0'; | |
449 | } | |
56d81795 CV |
450 | *stpncpy (opts, p->mnt_opts, noumount - p->mnt_opts) = '\0'; |
451 | printf (format_cyg, dirname, opts); | |
452 | break; | |
453 | } | |
e48feef9 | 454 | } |
56d81795 | 455 | endmntent (m); |
1b23b30b | 456 | |
bee722a5 CF |
457 | exit(0); |
458 | } | |
459 | ||
1fd5e000 CF |
460 | static void |
461 | show_mounts (void) | |
462 | { | |
463 | FILE *m = setmntent ("/-not-used-", "r"); | |
464 | struct mntent *p; | |
c6cd25a0 | 465 | const char *format = "%s on %s type %s (%s)\n"; |
1fd5e000 | 466 | |
c6cd25a0 | 467 | // printf (format, "Device", "Directory", "Type", "Flags"); |
1fd5e000 | 468 | while ((p = getmntent (m)) != NULL) |
c6cd25a0 | 469 | printf (format, p->mnt_fsname, p->mnt_dir, p->mnt_type, p->mnt_opts); |
1fd5e000 CF |
470 | endmntent (m); |
471 | } | |
472 | ||
473 | /* Return 1 if mountpoint from the same registry area is already in | |
474 | mount table. Otherwise return 0. */ | |
475 | static int | |
476 | mount_already_exists (const char *posix_path, int flags) | |
477 | { | |
478 | int found_matching = 0; | |
479 | ||
480 | FILE *m = setmntent ("/-not-used-", "r"); | |
481 | struct mntent *p; | |
482 | ||
483 | while ((p = getmntent (m)) != NULL) | |
484 | { | |
485 | /* if the paths match, and they're both the same type of mount. */ | |
486 | if (strcmp (p->mnt_dir, posix_path) == 0) | |
487 | { | |
44d2afed | 488 | if (p->mnt_type[0] == 'u') |
1fd5e000 | 489 | { |
9f425256 CF |
490 | if (!(flags & MOUNT_SYSTEM)) /* both current_user */ |
491 | found_matching = 1; | |
492 | else | |
493 | fprintf (stderr, | |
494 | "%s: warning: system mount point of '%s' " | |
495 | "will always be masked by user mount.\n", | |
496 | progname, posix_path); | |
1fd5e000 | 497 | break; |
9f425256 | 498 | } |
44d2afed | 499 | else if (p->mnt_type[0] == 's') |
1fd5e000 | 500 | { |
9f425256 CF |
501 | if (flags & MOUNT_SYSTEM) /* both system */ |
502 | found_matching = 1; | |
503 | else | |
504 | fprintf (stderr, | |
505 | "%s: warning: user mount point of '%s' " | |
92b499ac | 506 | "masks system mount.\n", progname, posix_path); |
1fd5e000 CF |
507 | break; |
508 | } | |
509 | else | |
510 | { | |
92b499ac CV |
511 | fprintf (stderr, "%s: warning: couldn't determine mount type.\n", |
512 | progname); | |
1fd5e000 CF |
513 | break; |
514 | } | |
515 | } | |
516 | } | |
517 | endmntent (m); | |
518 | ||
519 | return found_matching; | |
520 | } | |
521 | ||
522 | /* change_cygdrive_prefix: Change the cygdrive prefix */ | |
523 | static void | |
524 | change_cygdrive_prefix (const char *new_prefix, int flags) | |
525 | { | |
94cc482c | 526 | flags |= MOUNT_CYGDRIVE; |
1fd5e000 CF |
527 | |
528 | if (mount (NULL, new_prefix, flags)) | |
9500a3db | 529 | error (new_prefix); |
eedc36cb | 530 | |
1fd5e000 CF |
531 | exit (0); |
532 | } | |
959e1bac | 533 | |
be61cf4d | 534 | /* show_cygdrive_info: Show the user and/or cygdrive info, i.e., prefix and |
4c35f9f0 | 535 | flags.*/ |
959e1bac | 536 | static void |
4c35f9f0 | 537 | show_cygdrive_info () |
959e1bac | 538 | { |
4c35f9f0 | 539 | /* Get the cygdrive info */ |
959e1bac CF |
540 | char user[MAX_PATH]; |
541 | char system[MAX_PATH]; | |
4c35f9f0 CF |
542 | char user_flags[MAX_PATH]; |
543 | char system_flags[MAX_PATH]; | |
544 | cygwin_internal (CW_GET_CYGDRIVE_INFO, user, system, user_flags, | |
545 | system_flags); | |
959e1bac | 546 | |
be61cf4d | 547 | /* Display the user and system cygdrive path prefix, if necessary |
959e1bac | 548 | (ie, not empty) */ |
4c35f9f0 CF |
549 | const char *format = "%-18s %-11s %s\n"; |
550 | printf (format, "Prefix", "Type", "Flags"); | |
959e1bac | 551 | if (strlen (user) > 0) |
4c35f9f0 | 552 | printf (format, user, "user", user_flags); |
959e1bac | 553 | if (strlen (system) > 0) |
56d81795 | 554 | printf (format, system, "nouser", system_flags); |
959e1bac CF |
555 | |
556 | exit (0); | |
557 | } |