* src/vipw.c: Use a bool when possible instead of int integers.
* src/vipw.c: Ignore the return value of umask(), when the mask is set again to the old value. * src/vipw.c: Avoid implicit conversion of pointers / integers to booleans. * src/vipw.c: Add brackets and parenthesis. * src/vipw.c: Avoid assignments in comparisons. * src/vipw.c: Ignore return value of setlocale(), bindtextdomain(), and textdomain(). * src/vipw.c: Add missing termination of the longopts parameter for getopt_long().
This commit is contained in:
parent
45544f42b9
commit
fdb577e0a0
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
2008-06-09 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* src/vipw.c: Use a bool when possible instead of int integers.
|
||||||
|
* src/vipw.c: Ignore the return value of umask(), when the mask is
|
||||||
|
set again to the old value.
|
||||||
|
* src/vipw.c: Avoid implicit conversion of pointers / integers to
|
||||||
|
booleans.
|
||||||
|
* src/vipw.c: Add brackets and parenthesis.
|
||||||
|
* src/vipw.c: Avoid assignments in comparisons.
|
||||||
|
* src/vipw.c: Ignore return value of setlocale(),
|
||||||
|
bindtextdomain(), and textdomain().
|
||||||
|
* src/vipw.c: Add missing termination of the longopts parameter
|
||||||
|
for getopt_long().
|
||||||
|
|
||||||
2008-06-09 Nicolas François <nicolas.francois@centraliens.net>
|
2008-06-09 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* src/chgpasswd.c: Use a bool when possible instead of int
|
* src/chgpasswd.c: Use a bool when possible instead of int
|
||||||
|
111
src/vipw.c
111
src/vipw.c
@ -54,9 +54,10 @@
|
|||||||
* Global variables
|
* Global variables
|
||||||
*/
|
*/
|
||||||
static const char *progname, *filename, *fileeditname;
|
static const char *progname, *filename, *fileeditname;
|
||||||
static int filelocked = 0, createedit = 0;
|
static bool filelocked = false;
|
||||||
|
static bool createedit = false;
|
||||||
static int (*unlock) (void);
|
static int (*unlock) (void);
|
||||||
static int quiet = 0;
|
static bool quiet = false;
|
||||||
|
|
||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
static void usage (void);
|
static void usage (void);
|
||||||
@ -69,6 +70,7 @@ static void vipwedit (const char *, int (*)(void), int (*)(void));
|
|||||||
*/
|
*/
|
||||||
static void usage (void)
|
static void usage (void)
|
||||||
{
|
{
|
||||||
|
(void)
|
||||||
fputs (_("Usage: vipw [options]\n"
|
fputs (_("Usage: vipw [options]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
@ -93,31 +95,33 @@ static int create_backup_file (FILE * fp, const char *backup, struct stat *sb)
|
|||||||
|
|
||||||
mask = umask (077);
|
mask = umask (077);
|
||||||
bkfp = fopen (backup, "w");
|
bkfp = fopen (backup, "w");
|
||||||
umask (mask);
|
(void) umask (mask);
|
||||||
if (!bkfp)
|
if (NULL == bkfp) {
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
if (fseeko (fp, 0, SEEK_SET) == 0)
|
if (fseeko (fp, 0, SEEK_SET) == 0)
|
||||||
while ((c = getc (fp)) != EOF) {
|
while ((c = getc (fp)) != EOF) {
|
||||||
if (putc (c, bkfp) == EOF)
|
if (putc (c, bkfp) == EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (c != EOF || ferror (fp) || fflush (bkfp)) {
|
}
|
||||||
|
if ((EOF != c) || (ferror (fp) != 0) || (fflush (bkfp) != 0)) {
|
||||||
fclose (bkfp);
|
fclose (bkfp);
|
||||||
unlink (backup);
|
unlink (backup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (fclose (bkfp)) {
|
if (fclose (bkfp) != 0) {
|
||||||
unlink (backup);
|
unlink (backup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ub.actime = sb->st_atime;
|
ub.actime = sb->st_atime;
|
||||||
ub.modtime = sb->st_mtime;
|
ub.modtime = sb->st_mtime;
|
||||||
if (utime (backup, &ub) ||
|
if ( (utime (backup, &ub) != 0)
|
||||||
chmod (backup, sb->st_mode) ||
|
|| (chmod (backup, sb->st_mode) != 0)
|
||||||
chown (backup, sb->st_uid, sb->st_gid)) {
|
|| (chown (backup, sb->st_uid, sb->st_gid) != 0)) {
|
||||||
unlink (backup);
|
unlink (backup);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -131,17 +135,22 @@ static void vipwexit (const char *msg, int syserr, int ret)
|
|||||||
{
|
{
|
||||||
int err = errno;
|
int err = errno;
|
||||||
|
|
||||||
if (createedit)
|
if (createedit) {
|
||||||
unlink (fileeditname);
|
unlink (fileeditname);
|
||||||
if (filelocked)
|
}
|
||||||
|
if (filelocked) {
|
||||||
(*unlock) ();
|
(*unlock) ();
|
||||||
if (msg)
|
}
|
||||||
|
if (NULL != msg) {
|
||||||
fprintf (stderr, "%s: %s", progname, msg);
|
fprintf (stderr, "%s: %s", progname, msg);
|
||||||
if (syserr)
|
}
|
||||||
|
if (0 != syserr) {
|
||||||
fprintf (stderr, ": %s", strerror (err));
|
fprintf (stderr, ": %s", strerror (err));
|
||||||
if (!quiet)
|
}
|
||||||
|
if (!quiet) {
|
||||||
fprintf (stdout, _("\n%s: %s is unchanged\n"), progname,
|
fprintf (stdout, _("\n%s: %s is unchanged\n"), progname,
|
||||||
filename);
|
filename);
|
||||||
|
}
|
||||||
exit (ret);
|
exit (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,30 +177,39 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
filename = file;
|
filename = file;
|
||||||
fileeditname = fileedit;
|
fileeditname = fileedit;
|
||||||
|
|
||||||
if (access (file, F_OK))
|
if (access (file, F_OK) != 0) {
|
||||||
vipwexit (file, 1, 1);
|
vipwexit (file, 1, 1);
|
||||||
if (!file_lock ())
|
}
|
||||||
|
if (file_lock () == 0) {
|
||||||
vipwexit (_("Couldn't lock file"), errno, 5);
|
vipwexit (_("Couldn't lock file"), errno, 5);
|
||||||
filelocked = 1;
|
}
|
||||||
|
filelocked = true;
|
||||||
|
|
||||||
/* edited copy has same owners, perm */
|
/* edited copy has same owners, perm */
|
||||||
if (stat (file, &st1))
|
if (stat (file, &st1) != 0) {
|
||||||
vipwexit (file, 1, 1);
|
vipwexit (file, 1, 1);
|
||||||
if (!(f = fopen (file, "r")))
|
}
|
||||||
|
f = fopen (file, "r");
|
||||||
|
if (NULL == f) {
|
||||||
vipwexit (file, 1, 1);
|
vipwexit (file, 1, 1);
|
||||||
if (create_backup_file (f, fileedit, &st1))
|
}
|
||||||
|
if (create_backup_file (f, fileedit, &st1) != 0) {
|
||||||
vipwexit (_("Couldn't make backup"), errno, 1);
|
vipwexit (_("Couldn't make backup"), errno, 1);
|
||||||
createedit = 1;
|
}
|
||||||
|
createedit = true;
|
||||||
|
|
||||||
editor = getenv ("VISUAL");
|
editor = getenv ("VISUAL");
|
||||||
if (!editor)
|
if (NULL == editor) {
|
||||||
editor = getenv ("EDITOR");
|
editor = getenv ("EDITOR");
|
||||||
if (!editor)
|
}
|
||||||
|
if (NULL == editor) {
|
||||||
editor = DEFAULT_EDITOR;
|
editor = DEFAULT_EDITOR;
|
||||||
|
}
|
||||||
|
|
||||||
if ((pid = fork ()) == -1)
|
pid = fork ();
|
||||||
|
if (-1 == pid) {
|
||||||
vipwexit ("fork", 1, 1);
|
vipwexit ("fork", 1, 1);
|
||||||
else if (!pid) {
|
} else if (0 == pid) {
|
||||||
/* use the system() call to invoke the editor so that it accepts
|
/* use the system() call to invoke the editor so that it accepts
|
||||||
command line args in the EDITOR and VISUAL environment vars */
|
command line args in the EDITOR and VISUAL environment vars */
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -203,36 +221,43 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
fprintf (stderr, "%s: %s: %s\n", progname, editor,
|
fprintf (stderr, "%s: %s: %s\n", progname, editor,
|
||||||
strerror (errno));
|
strerror (errno));
|
||||||
exit (1);
|
exit (1);
|
||||||
} else
|
} else {
|
||||||
exit (0);
|
exit (0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pid = waitpid (pid, &status, WUNTRACED);
|
pid = waitpid (pid, &status, WUNTRACED);
|
||||||
if ((pid != -1) && WIFSTOPPED (status)) {
|
if ((pid != -1) && (WIFSTOPPED (status) != 0)) {
|
||||||
/* The child (editor) was suspended.
|
/* The child (editor) was suspended.
|
||||||
* Suspend vipw. */
|
* Suspend vipw. */
|
||||||
kill (getpid (), WSTOPSIG(status));
|
kill (getpid (), WSTOPSIG(status));
|
||||||
/* wake child when resumed */
|
/* wake child when resumed */
|
||||||
kill (pid, SIGCONT);
|
kill (pid, SIGCONT);
|
||||||
} else
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (pid == -1 || !WIFEXITED (status) || WEXITSTATUS (status))
|
if ( (-1 == pid)
|
||||||
|
|| (WIFEXITED (status) == 0)
|
||||||
|
|| (WEXITSTATUS (status) != 0)) {
|
||||||
vipwexit (editor, 1, 1);
|
vipwexit (editor, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (stat (fileedit, &st2))
|
if (stat (fileedit, &st2) != 0) {
|
||||||
vipwexit (fileedit, 1, 1);
|
vipwexit (fileedit, 1, 1);
|
||||||
if (st1.st_mtime == st2.st_mtime)
|
}
|
||||||
|
if (st1.st_mtime == st2.st_mtime) {
|
||||||
vipwexit (0, 0, 0);
|
vipwexit (0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXX - here we should check fileedit for errors; if there are any,
|
* XXX - here we should check fileedit for errors; if there are any,
|
||||||
* ask the user what to do (edit again, save changes anyway, or quit
|
* ask the user what to do (edit again, save changes anyway, or quit
|
||||||
* without saving). Use pwck or grpck to do the check. --marekm
|
* without saving). Use pwck or grpck to do the check. --marekm
|
||||||
*/
|
*/
|
||||||
createedit = 0;
|
createedit = false;
|
||||||
unlink (filebackup);
|
unlink (filebackup);
|
||||||
link (file, filebackup);
|
link (file, filebackup);
|
||||||
if (rename (fileedit, file) == -1) {
|
if (rename (fileedit, file) == -1) {
|
||||||
@ -248,13 +273,13 @@ vipwedit (const char *file, int (*file_lock) (void), int (*file_unlock) (void))
|
|||||||
|
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int editshadow = 0;
|
bool editshadow = false;
|
||||||
char *a;
|
char *a;
|
||||||
int do_vipw;
|
bool do_vipw;
|
||||||
|
|
||||||
setlocale (LC_ALL, "");
|
(void) setlocale (LC_ALL, "");
|
||||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||||
textdomain (PACKAGE);
|
(void) textdomain (PACKAGE);
|
||||||
|
|
||||||
progname = ((a = strrchr (*argv, '/')) ? a + 1 : *argv);
|
progname = ((a = strrchr (*argv, '/')) ? a + 1 : *argv);
|
||||||
do_vipw = (strcmp (progname, "vigr") != 0);
|
do_vipw = (strcmp (progname, "vigr") != 0);
|
||||||
@ -270,25 +295,26 @@ int main (int argc, char **argv)
|
|||||||
{"passwd", no_argument, NULL, 'p'},
|
{"passwd", no_argument, NULL, 'p'},
|
||||||
{"quiet", no_argument, NULL, 'q'},
|
{"quiet", no_argument, NULL, 'q'},
|
||||||
{"shadow", no_argument, NULL, 's'},
|
{"shadow", no_argument, NULL, 's'},
|
||||||
|
{NULL, 0, NULL, '\0'}
|
||||||
};
|
};
|
||||||
while ((c =
|
while ((c =
|
||||||
getopt_long (argc, argv, "ghpqs",
|
getopt_long (argc, argv, "ghpqs",
|
||||||
long_options, NULL)) != -1) {
|
long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'g':
|
case 'g':
|
||||||
do_vipw = 0;
|
do_vipw = false;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage ();
|
usage ();
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
do_vipw = 1;
|
do_vipw = true;
|
||||||
break;
|
break;
|
||||||
case 'q':
|
case 'q':
|
||||||
quiet = 1;
|
quiet = true;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
editshadow = 1;
|
editshadow = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage ();
|
usage ();
|
||||||
@ -339,3 +365,4 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
exit (E_SUCCESS);
|
exit (E_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user