|
Lines 1-7
Link Here
|
| 1 |
/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> |
1 |
/* |
|
|
2 |
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> |
| 2 |
* - added Native Language Support |
3 |
* - added Native Language Support |
| 3 |
* Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
4 |
* 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br> |
| 4 |
* - fixed strerr(errno) in gettext calls |
5 |
* - fixed strerr(errno) in gettext calls |
|
|
6 |
* 2003-08-08 Thomas Hood <jdthood@yahoo.co.uk> with help from Patrick McLean |
| 7 |
* - Write through a symlink at /etc/mtab if it doesn't point into /proc/ |
| 5 |
*/ |
8 |
*/ |
| 6 |
|
9 |
|
| 7 |
#include <unistd.h> |
10 |
#include <unistd.h> |
|
Lines 11-77
Link Here
|
| 11 |
#include <sys/stat.h> |
14 |
#include <sys/stat.h> |
| 12 |
#include "mntent.h" |
15 |
#include "mntent.h" |
| 13 |
#include "fstab.h" |
16 |
#include "fstab.h" |
|
|
17 |
#include "realpath.h" |
| 14 |
#include "sundries.h" |
18 |
#include "sundries.h" |
| 15 |
#include "xmalloc.h" |
19 |
#include "xmalloc.h" |
| 16 |
#include "mount_blkid.h" |
20 |
#include "mount_blkid.h" |
| 17 |
#include "paths.h" |
21 |
#include "paths.h" |
| 18 |
#include "nls.h" |
22 |
#include "nls.h" |
| 19 |
|
23 |
|
| 20 |
#define streq(s, t) (strcmp ((s), (t)) == 0) |
|
|
| 21 |
|
| 22 |
#define PROC_MOUNTS "/proc/mounts" |
| 23 |
|
| 24 |
|
| 25 |
/* Information about mtab. ------------------------------------*/ |
24 |
/* Information about mtab. ------------------------------------*/ |
| 26 |
static int have_mtab_info = 0; |
25 |
/* A 64 bit number can be displayed in 20 decimal digits */ |
| 27 |
static int var_mtab_does_not_exist = 0; |
26 |
#define LEN_LARGEST_PID 20 |
| 28 |
static int var_mtab_is_a_symlink = 0; |
27 |
#define MTAB_PATH_MAX (PATH_MAX - (sizeof(MTAB_LOCK_SUFFIX) - 1) - LEN_LARGEST_PID) |
|
|
28 |
static char mtab_path[MTAB_PATH_MAX]; |
| 29 |
static char mtab_lock_path[PATH_MAX]; |
| 30 |
static char mtab_lock_targ[PATH_MAX]; |
| 31 |
static char mtab_temp_path[PATH_MAX]; |
| 29 |
|
32 |
|
| 30 |
static void |
33 |
/* |
|
|
34 |
* Set mtab_path to the real path of the mtab file |
| 35 |
* or to the null string if that path is inaccessible |
| 36 |
* |
| 37 |
* Run this early |
| 38 |
*/ |
| 39 |
void |
| 31 |
get_mtab_info(void) { |
40 |
get_mtab_info(void) { |
| 32 |
struct stat mtab_stat; |
41 |
struct stat mtab_stat; |
| 33 |
|
42 |
|
| 34 |
if (!have_mtab_info) { |
43 |
if (lstat(MOUNTED, &mtab_stat)) { |
| 35 |
if (lstat(MOUNTED, &mtab_stat)) |
44 |
/* Assume that the lstat error means that the file does not exist */ |
| 36 |
var_mtab_does_not_exist = 1; |
45 |
/* (Maybe we should check errno here) */ |
| 37 |
else if (S_ISLNK(mtab_stat.st_mode)) |
46 |
strcpy(mtab_path, MOUNTED); |
| 38 |
var_mtab_is_a_symlink = 1; |
47 |
} else if (S_ISLNK(mtab_stat.st_mode)) { |
| 39 |
have_mtab_info = 1; |
48 |
/* Is a symlink */ |
|
|
49 |
int len; |
| 50 |
char *r = myrealpath(MOUNTED, mtab_path, MTAB_PATH_MAX); |
| 51 |
mtab_path[MTAB_PATH_MAX - 1] = 0; /* Just to be sure */ |
| 52 |
len = strlen(mtab_path); |
| 53 |
if ( |
| 54 |
r == NULL |
| 55 |
|| len == 0 |
| 56 |
|| len >= (MTAB_PATH_MAX - 1) |
| 57 |
|| streqn(mtab_path, PATH_PROC, sizeof(PATH_PROC) - 1) |
| 58 |
) { |
| 59 |
/* Real path invalid or inaccessible */ |
| 60 |
mtab_path[0] = '\0'; |
| 61 |
return; |
| 62 |
} |
| 63 |
/* mtab_path now contains mtab's real path */ |
| 64 |
} else { |
| 65 |
/* Exists and is not a symlink */ |
| 66 |
strcpy(mtab_path, MOUNTED); |
| 40 |
} |
67 |
} |
|
|
68 |
|
| 69 |
sprintf(mtab_lock_path, "%s%s", mtab_path, MTAB_LOCK_SUFFIX); |
| 70 |
sprintf(mtab_lock_targ, "%s%s%d", mtab_path, MTAB_LOCK_SUFFIX, getpid()); |
| 71 |
sprintf(mtab_temp_path, "%s%s", mtab_path, MTAB_TEMP_SUFFIX); |
| 72 |
|
| 73 |
return; |
| 41 |
} |
74 |
} |
| 42 |
|
75 |
|
| 43 |
int |
76 |
/* |
| 44 |
mtab_does_not_exist(void) { |
77 |
* Tell whether or not the mtab real path is accessible |
| 45 |
get_mtab_info(); |
78 |
* |
| 46 |
return var_mtab_does_not_exist; |
79 |
* get_mtab_info() must have been run |
|
|
80 |
*/ |
| 81 |
static int |
| 82 |
mtab_is_accessible(void) { |
| 83 |
return (mtab_path[0] != '\0'); |
| 47 |
} |
84 |
} |
| 48 |
|
85 |
|
|
|
86 |
/* |
| 87 |
* Tell whether or not the mtab file currently exists |
| 88 |
* |
| 89 |
* Note that the answer here is independent of whether or |
| 90 |
* not the file is writable, so if you are planning to create |
| 91 |
* the mtab file then check mtab_is_writable() too. |
| 92 |
* |
| 93 |
* get_mtab_info() must have been run |
| 94 |
*/ |
| 49 |
int |
95 |
int |
| 50 |
mtab_is_a_symlink(void) { |
96 |
mtab_does_not_exist(void) { |
| 51 |
get_mtab_info(); |
97 |
struct stat mtab_stat; |
| 52 |
return var_mtab_is_a_symlink; |
98 |
|
|
|
99 |
if (!mtab_is_accessible()) |
| 100 |
return 1; |
| 101 |
|
| 102 |
if (lstat(mtab_path, &mtab_stat)) |
| 103 |
return 1; |
| 104 |
|
| 105 |
return 0; |
| 53 |
} |
106 |
} |
| 54 |
|
107 |
|
|
|
108 |
/* |
| 109 |
* Tell whether or not mtab is writable (whether or not it currently exists) |
| 110 |
* |
| 111 |
* This depends on whether or not the real path is accessible and, |
| 112 |
* if so, whether or not the file can be opened. This function |
| 113 |
* has the side effect of creating the file if it is writable. |
| 114 |
* |
| 115 |
* get_mtab_info() must have been run |
| 116 |
*/ |
| 55 |
int |
117 |
int |
| 56 |
mtab_is_writable() { |
118 |
mtab_is_writable() { |
| 57 |
static int ret = -1; |
119 |
static int is_writable = -1; |
|
|
120 |
int fd; |
| 121 |
|
| 122 |
if (is_writable != -1) |
| 123 |
return is_writable; |
| 58 |
|
124 |
|
| 59 |
/* Should we write to /etc/mtab upon an update? |
125 |
if (!mtab_is_accessible()) { |
| 60 |
Probably not if it is a symlink to /proc/mounts, since that |
126 |
is_writable = 0; |
| 61 |
would create a file /proc/mounts in case the proc filesystem |
127 |
return is_writable; |
| 62 |
is not mounted. */ |
|
|
| 63 |
if (mtab_is_a_symlink()) |
| 64 |
return 0; |
| 65 |
|
| 66 |
if (ret == -1) { |
| 67 |
int fd = open(MOUNTED, O_RDWR | O_CREAT, 0644); |
| 68 |
if (fd >= 0) { |
| 69 |
close(fd); |
| 70 |
ret = 1; |
| 71 |
} else |
| 72 |
ret = 0; |
| 73 |
} |
128 |
} |
| 74 |
return ret; |
129 |
|
|
|
130 |
fd = open(mtab_path, O_RDWR | O_CREAT, 0644); |
| 131 |
if (fd >= 0) { |
| 132 |
close(fd); |
| 133 |
is_writable = 1; |
| 134 |
} else { |
| 135 |
is_writable = 0; |
| 136 |
} |
| 137 |
return is_writable; |
| 75 |
} |
138 |
} |
| 76 |
|
139 |
|
| 77 |
/* Contents of mtab and fstab ---------------------------------*/ |
140 |
/* Contents of mtab and fstab ---------------------------------*/ |
|
Lines 154-174
Link Here
|
| 154 |
got_mtab = 1; |
217 |
got_mtab = 1; |
| 155 |
mc->nxt = mc->prev = NULL; |
218 |
mc->nxt = mc->prev = NULL; |
| 156 |
|
219 |
|
| 157 |
fnam = MOUNTED; |
220 |
fnam = mtab_path; |
| 158 |
mfp = my_setmntent (fnam, "r"); |
221 |
mfp = my_setmntent (fnam, "r"); |
| 159 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
222 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
| 160 |
int errsv = errno; |
223 |
int errsv = errno; |
| 161 |
fnam = PROC_MOUNTS; |
224 |
fnam = PATH_PROC_MOUNTS; |
| 162 |
mfp = my_setmntent (fnam, "r"); |
225 |
mfp = my_setmntent (fnam, "r"); |
| 163 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
226 |
if (mfp == NULL || mfp->mntent_fp == NULL) { |
| 164 |
error(_("warning: can't open %s: %s"), |
227 |
error(_("warning: can't open %s: %s"), |
| 165 |
MOUNTED, strerror (errsv)); |
228 |
mtab_path, strerror (errsv)); |
| 166 |
return; |
229 |
return; |
| 167 |
} |
230 |
} |
| 168 |
if (verbose) |
231 |
if (verbose) |
| 169 |
printf (_("mount: could not open %s - " |
232 |
printf (_("mount: could not open %s - " |
| 170 |
"using %s instead\n"), |
233 |
"using %s instead\n"), |
| 171 |
MOUNTED, PROC_MOUNTS); |
234 |
mtab_path, PATH_PROC_MOUNTS); |
| 172 |
} |
235 |
} |
| 173 |
read_mntentchn(mfp, fnam, mc); |
236 |
read_mntentchn(mfp, fnam, mc); |
| 174 |
} |
237 |
} |
|
Lines 396-404
Link Here
|
| 396 |
/* Flag for already existing lock file. */ |
459 |
/* Flag for already existing lock file. */ |
| 397 |
static int we_created_lockfile = 0; |
460 |
static int we_created_lockfile = 0; |
| 398 |
|
461 |
|
| 399 |
/* Flag to indicate that signals have been set up. */ |
|
|
| 400 |
static int signals_have_been_setup = 0; |
| 401 |
|
| 402 |
/* Ensure that the lock is released if we are interrupted. */ |
462 |
/* Ensure that the lock is released if we are interrupted. */ |
| 403 |
extern char *strsignal(int sig); /* not always in <string.h> */ |
463 |
extern char *strsignal(int sig); /* not always in <string.h> */ |
| 404 |
|
464 |
|
|
Lines 416-450
Link Here
|
| 416 |
void |
476 |
void |
| 417 |
unlock_mtab (void) { |
477 |
unlock_mtab (void) { |
| 418 |
if (we_created_lockfile) { |
478 |
if (we_created_lockfile) { |
| 419 |
unlink (MOUNTED_LOCK); |
479 |
unlink (mtab_lock_path); |
| 420 |
we_created_lockfile = 0; |
480 |
we_created_lockfile = 0; |
| 421 |
} |
481 |
} |
| 422 |
} |
482 |
} |
| 423 |
|
483 |
|
| 424 |
/* Create the lock file. |
484 |
/* |
| 425 |
The lock file will be removed if we catch a signal or when we exit. */ |
485 |
* Create the lock file |
|
|
486 |
* |
| 487 |
* The lock file will be removed if we catch a signal or when we exit |
| 488 |
*/ |
| 426 |
/* The old code here used flock on a lock file /etc/mtab~ and deleted |
489 |
/* The old code here used flock on a lock file /etc/mtab~ and deleted |
| 427 |
this lock file afterwards. However, as rgooch remarks, that has a |
490 |
this lock file afterwards. However, as rgooch remarks, that races: |
| 428 |
race: a second mount may be waiting on the lock and proceed as |
491 |
a second mount may be waiting on the lock which will proceed as |
| 429 |
soon as the lock file is deleted by the first mount, and immediately |
492 |
soon as the lock file is deleted by the first mount; immediately |
| 430 |
afterwards a third mount comes, creates a new /etc/mtab~, applies |
493 |
afterwards a third mount can come, create a new /etc/mtab~, apply |
| 431 |
flock to that, and also proceeds, so that the second and third mount |
494 |
flock to that, and also proceed, so that the second and third mount |
| 432 |
now both are scribbling in /etc/mtab. |
495 |
now both scribble in /etc/mtab. |
| 433 |
The new code uses a link() instead of a creat(), where we proceed |
496 |
The new code uses a link() instead of a creat(), where we proceed |
| 434 |
only if it was us that created the lock, and hence we always have |
497 |
only if it was we that created the lock, and hence we always have |
| 435 |
to delete the lock afterwards. Now the use of flock() is in principle |
498 |
to delete the lock afterwards. Now the use of flock() is in principle |
| 436 |
superfluous, but avoids an arbitrary sleep(). */ |
499 |
superfluous, but using it allows us to avoid an arbitrary sleep(). */ |
| 437 |
|
|
|
| 438 |
/* Where does the link point to? Obvious choices are mtab and mtab~~. |
| 439 |
HJLu points out that the latter leads to races. Right now we use |
| 440 |
mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */ |
| 441 |
#define MOUNTLOCK_LINKTARGET MOUNTED_LOCK "%d" |
| 442 |
#define MOUNTLOCK_LINKTARGET_LTH (sizeof(MOUNTED_LOCK)+20) |
| 443 |
|
500 |
|
| 444 |
void |
501 |
void |
| 445 |
lock_mtab (void) { |
502 |
lock_mtab (void) { |
| 446 |
int tries = 3; |
503 |
int tries = 3; |
| 447 |
char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; |
504 |
/* Flag to indicate that signals have been set up. */ |
|
|
505 |
static int signals_have_been_setup = 0; |
| 448 |
|
506 |
|
| 449 |
at_die = unlock_mtab; |
507 |
at_die = unlock_mtab; |
| 450 |
|
508 |
|
|
Lines 467-496
Link Here
|
| 467 |
signals_have_been_setup = 1; |
525 |
signals_have_been_setup = 1; |
| 468 |
} |
526 |
} |
| 469 |
|
527 |
|
| 470 |
sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ()); |
|
|
| 471 |
|
| 472 |
/* Repeat until it was us who made the link */ |
528 |
/* Repeat until it was us who made the link */ |
| 473 |
while (!we_created_lockfile) { |
529 |
while (!we_created_lockfile) { |
| 474 |
struct flock flock; |
530 |
struct flock flock; |
| 475 |
int errsv, fd, i, j; |
531 |
int errsv, fd, i, j; |
| 476 |
|
532 |
|
| 477 |
i = open (linktargetfile, O_WRONLY|O_CREAT, 0); |
533 |
i = open (mtab_lock_targ, O_WRONLY|O_CREAT, 0); |
| 478 |
if (i < 0) { |
534 |
if (i < 0) { |
| 479 |
int errsv = errno; |
535 |
int errsv = errno; |
| 480 |
/* linktargetfile does not exist (as a file) |
536 |
/* mtab_lock_targ does not exist (as a file) |
| 481 |
and we cannot create it. Read-only filesystem? |
537 |
and we cannot create it. Read-only filesystem? |
| 482 |
Too many files open in the system? |
538 |
Too many files open in the system? |
| 483 |
Filesystem full? */ |
539 |
Filesystem full? */ |
| 484 |
die (EX_FILEIO, _("can't create lock file %s: %s " |
540 |
die (EX_FILEIO, _("can't create lock file %s: %s " |
| 485 |
"(use -n flag to override)"), |
541 |
"(use -n flag to override)"), |
| 486 |
linktargetfile, strerror (errsv)); |
542 |
mtab_lock_targ, strerror (errsv)); |
| 487 |
} |
543 |
} |
| 488 |
close(i); |
544 |
close(i); |
| 489 |
|
545 |
|
| 490 |
j = link(linktargetfile, MOUNTED_LOCK); |
546 |
j = link(mtab_lock_targ, mtab_lock_path); |
| 491 |
errsv = errno; |
547 |
errsv = errno; |
| 492 |
|
548 |
|
| 493 |
(void) unlink(linktargetfile); |
549 |
(void) unlink(mtab_lock_targ); |
| 494 |
|
550 |
|
| 495 |
if (j == 0) |
551 |
if (j == 0) |
| 496 |
we_created_lockfile = 1; |
552 |
we_created_lockfile = 1; |
|
Lines 498-507
Link Here
|
| 498 |
if (j < 0 && errsv != EEXIST) { |
554 |
if (j < 0 && errsv != EEXIST) { |
| 499 |
die (EX_FILEIO, _("can't link lock file %s: %s " |
555 |
die (EX_FILEIO, _("can't link lock file %s: %s " |
| 500 |
"(use -n flag to override)"), |
556 |
"(use -n flag to override)"), |
| 501 |
MOUNTED_LOCK, strerror (errsv)); |
557 |
mtab_lock_path, strerror (errsv)); |
| 502 |
} |
558 |
} |
| 503 |
|
559 |
|
| 504 |
fd = open (MOUNTED_LOCK, O_WRONLY); |
560 |
fd = open (mtab_lock_path, O_WRONLY); |
| 505 |
|
561 |
|
| 506 |
if (fd < 0) { |
562 |
if (fd < 0) { |
| 507 |
int errsv = errno; |
563 |
int errsv = errno; |
|
Lines 510-516
Link Here
|
| 510 |
continue; |
566 |
continue; |
| 511 |
die (EX_FILEIO, _("can't open lock file %s: %s " |
567 |
die (EX_FILEIO, _("can't open lock file %s: %s " |
| 512 |
"(use -n flag to override)"), |
568 |
"(use -n flag to override)"), |
| 513 |
MOUNTED_LOCK, strerror (errsv)); |
569 |
mtab_lock_path, strerror (errsv)); |
| 514 |
} |
570 |
} |
| 515 |
|
571 |
|
| 516 |
flock.l_type = F_WRLCK; |
572 |
flock.l_type = F_WRLCK; |
|
Lines 524-530
Link Here
|
| 524 |
if (verbose) { |
580 |
if (verbose) { |
| 525 |
int errsv = errno; |
581 |
int errsv = errno; |
| 526 |
printf(_("Can't lock lock file %s: %s\n"), |
582 |
printf(_("Can't lock lock file %s: %s\n"), |
| 527 |
MOUNTED_LOCK, strerror (errsv)); |
583 |
mtab_lock_path, strerror (errsv)); |
| 528 |
} |
584 |
} |
| 529 |
/* proceed anyway */ |
585 |
/* proceed anyway */ |
| 530 |
} |
586 |
} |
|
Lines 536-552
Link Here
|
| 536 |
if (fcntl (fd, F_SETLKW, &flock) == -1) { |
592 |
if (fcntl (fd, F_SETLKW, &flock) == -1) { |
| 537 |
int errsv = errno; |
593 |
int errsv = errno; |
| 538 |
die (EX_FILEIO, _("can't lock lock file %s: %s"), |
594 |
die (EX_FILEIO, _("can't lock lock file %s: %s"), |
| 539 |
MOUNTED_LOCK, (errno == EINTR) ? |
595 |
mtab_lock_path, (errno == EINTR) ? |
| 540 |
_("timed out") : strerror (errsv)); |
596 |
_("timed out") : strerror (errsv)); |
| 541 |
} |
597 |
} |
| 542 |
alarm(0); |
598 |
alarm(0); |
| 543 |
/* Limit the number of iterations - maybe there |
599 |
/* Limit the number of iterations - maybe there |
| 544 |
still is some old /etc/mtab~ */ |
600 |
still is some old lock */ |
| 545 |
if (tries++ > 3) { |
601 |
if (tries++ > 3) { |
| 546 |
if (tries > 5) |
602 |
if (tries > 5) |
| 547 |
die (EX_FILEIO, _("Cannot create link %s\n" |
603 |
die (EX_FILEIO, _("Cannot create link %s\n" |
| 548 |
"Perhaps there is a stale lock file?\n"), |
604 |
"Perhaps there is a stale lock file?\n"), |
| 549 |
MOUNTED_LOCK); |
605 |
mtab_lock_path); |
| 550 |
sleep(1); |
606 |
sleep(1); |
| 551 |
} |
607 |
} |
| 552 |
} |
608 |
} |
|
Lines 568-583
Link Here
|
| 568 |
void |
624 |
void |
| 569 |
update_mtab (const char *dir, struct my_mntent *instead) { |
625 |
update_mtab (const char *dir, struct my_mntent *instead) { |
| 570 |
mntFILE *mfp, *mftmp; |
626 |
mntFILE *mfp, *mftmp; |
| 571 |
const char *fnam = MOUNTED; |
627 |
const char *fnam = mtab_path; |
| 572 |
struct mntentchn mtabhead; /* dummy */ |
628 |
struct mntentchn mtabhead; /* dummy */ |
| 573 |
struct mntentchn *mc, *mc0, *absent = NULL; |
629 |
struct mntentchn *mc, *mc0, *absent = NULL; |
| 574 |
|
630 |
|
| 575 |
if (mtab_does_not_exist() || mtab_is_a_symlink()) |
631 |
if (mtab_does_not_exist()) |
| 576 |
return; |
632 |
return; |
| 577 |
|
633 |
|
| 578 |
lock_mtab(); |
634 |
lock_mtab(); |
| 579 |
|
635 |
|
| 580 |
/* having locked mtab, read it again */ |
636 |
/* Having got the lock, we read mtab again */ |
| 581 |
mc0 = mc = &mtabhead; |
637 |
mc0 = mc = &mtabhead; |
| 582 |
mc->nxt = mc->prev = NULL; |
638 |
mc->nxt = mc->prev = NULL; |
| 583 |
|
639 |
|
|
Lines 636-646
Link Here
|
| 636 |
} |
692 |
} |
| 637 |
|
693 |
|
| 638 |
/* write chain to mtemp */ |
694 |
/* write chain to mtemp */ |
| 639 |
mftmp = my_setmntent (MOUNTED_TEMP, "w"); |
695 |
mftmp = my_setmntent (mtab_temp_path, "w"); |
| 640 |
if (mftmp == NULL || mftmp->mntent_fp == NULL) { |
696 |
if (mftmp == NULL || mftmp->mntent_fp == NULL) { |
| 641 |
int errsv = errno; |
697 |
int errsv = errno; |
| 642 |
error (_("cannot open %s (%s) - mtab not updated"), |
698 |
error (_("cannot open %s (%s) - mtab not updated"), |
| 643 |
MOUNTED_TEMP, strerror (errsv)); |
699 |
mtab_temp_path, strerror (errsv)); |
| 644 |
/* Do not leak memory */ |
700 |
/* Do not leak memory */ |
| 645 |
discard_mntentchn(mc0); |
701 |
discard_mntentchn(mc0); |
| 646 |
goto leave; |
702 |
goto leave; |
|
Lines 650-656
Link Here
|
| 650 |
if (my_addmntent(mftmp, &(mc->m)) == 1) { |
706 |
if (my_addmntent(mftmp, &(mc->m)) == 1) { |
| 651 |
int errsv = errno; |
707 |
int errsv = errno; |
| 652 |
die (EX_FILEIO, _("error writing %s: %s"), |
708 |
die (EX_FILEIO, _("error writing %s: %s"), |
| 653 |
MOUNTED_TEMP, strerror (errsv)); |
709 |
mtab_temp_path, strerror (errsv)); |
| 654 |
} |
710 |
} |
| 655 |
} |
711 |
} |
| 656 |
|
712 |
|
|
Lines 660-684
Link Here
|
| 660 |
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { |
716 |
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { |
| 661 |
int errsv = errno; |
717 |
int errsv = errno; |
| 662 |
fprintf(stderr, _("error changing mode of %s: %s\n"), |
718 |
fprintf(stderr, _("error changing mode of %s: %s\n"), |
| 663 |
MOUNTED_TEMP, strerror (errsv)); |
719 |
mtab_temp_path, strerror (errsv)); |
| 664 |
} |
720 |
} |
| 665 |
my_endmntent (mftmp); |
721 |
my_endmntent (mftmp); |
| 666 |
|
722 |
|
| 667 |
{ /* |
723 |
{ /* |
| 668 |
* If mount is setuid and some non-root user mounts sth, |
724 |
* If mount is setuid and some non-root user mounts sth, |
| 669 |
* then mtab.tmp might get the group of this user. Copy uid/gid |
725 |
* then the temp file might get the group of this user. |
| 670 |
* from the present mtab before renaming. |
726 |
* Copy uid/gid from the present mtab before renaming. |
| 671 |
*/ |
727 |
*/ |
| 672 |
struct stat sbuf; |
728 |
struct stat sbuf; |
| 673 |
if (stat (MOUNTED, &sbuf) == 0) |
729 |
if (stat (mtab_path, &sbuf) == 0) |
| 674 |
chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid); |
730 |
chown (mtab_temp_path, sbuf.st_uid, sbuf.st_gid); |
| 675 |
} |
731 |
} |
| 676 |
|
732 |
|
| 677 |
/* rename mtemp to mtab */ |
733 |
/* rename mtemp to mtab */ |
| 678 |
if (rename (MOUNTED_TEMP, MOUNTED) < 0) { |
734 |
if (rename (mtab_temp_path, mtab_path) < 0) { |
| 679 |
int errsv = errno; |
735 |
int errsv = errno; |
| 680 |
fprintf(stderr, _("can't rename %s to %s: %s\n"), |
736 |
fprintf(stderr, _("can't rename %s to %s: %s\n"), |
| 681 |
MOUNTED_TEMP, MOUNTED, strerror(errsv)); |
737 |
mtab_temp_path, mtab_path, strerror(errsv)); |
| 682 |
} |
738 |
} |
| 683 |
|
739 |
|
| 684 |
leave: |
740 |
leave: |