]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - login-utils/vipw.c
docs: update year in libs docs
[thirdparty/util-linux.git] / login-utils / vipw.c
index 4d85924346a1c7ff3ba52895e1e35e772275884d..a071b639dd03e1926c07405941de64479bd62a8e 100644 (file)
@@ -61,6 +61,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <getopt.h>
 
 #include "c.h"
 #include "fileutils.h"
@@ -99,6 +100,9 @@ static void copyfile(int from, int to)
 
        if (nr < 0)
                pw_error(orig_file, 1, 1);
+#ifdef HAVE_EXPLICIT_BZERO
+       explicit_bzero(buf, sizeof(buf));
+#endif
 }
 
 static void pw_init(void)
@@ -205,8 +209,7 @@ static void pw_edit(void)
 
        if (!pid) {
                execlp(editor, p, tmp_file, NULL);
-               /* Shouldn't get here */
-               _exit(EXIT_FAILURE);
+               errexec(editor);
        }
        for (;;) {
                pid = waitpid(pid, &pstat, WUNTRACED);
@@ -253,7 +256,7 @@ static void edit_file(int is_shadow)
        if (lckpwdf() < 0)
                err(EXIT_FAILURE, _("cannot get lock"));
 
-       passwd_file = open(orig_file, O_RDONLY, 0);
+       passwd_file = open(orig_file, O_RDONLY | O_CLOEXEC, 0);
        if (passwd_file < 0)
                err(EXIT_FAILURE, _("cannot open %s"), orig_file);
        tmp_fd = pw_tmpfile(passwd_file);
@@ -271,7 +274,7 @@ static void edit_file(int is_shadow)
        if (end.st_nlink == 0) {
                if (close_stream(tmp_fd) != 0)
                        err(EXIT_FAILURE, _("write error"));
-               tmp_fd = fopen(tmp_file, "r");
+               tmp_fd = fopen(tmp_file, "r" UL_CLOEXECSTR);
                if (!tmp_fd)
                        err(EXIT_FAILURE, _("cannot open %s"), tmp_file);
                if (fstat(fileno(tmp_fd), &end))
@@ -295,8 +298,9 @@ static void edit_file(int is_shadow)
        ulckpwdf();
 }
 
-static void __attribute__((__noreturn__)) usage(FILE *out)
+static void __attribute__((__noreturn__)) usage(void)
 {
+       FILE *out = stdout;
        fputs(USAGE_HEADER, out);
        fprintf(out, " %s\n", program_invocation_short_name);
 
@@ -304,18 +308,24 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
        fputs(_("Edit the password or group file.\n"), out);
 
        fputs(USAGE_OPTIONS, out);
-       fputs(USAGE_HELP, out);
-       fputs(USAGE_VERSION, out);
-       fprintf(out, USAGE_MAN_TAIL("vipw(8)"));
-       exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+       printf(USAGE_HELP_OPTIONS(16));
+       printf(USAGE_MAN_TAIL("vipw(8)"));
+       exit(EXIT_SUCCESS);
 }
 
 int main(int argc, char *argv[])
 {
+       int c;
+       static const struct option longopts[] = {
+               {"version", no_argument, NULL, 'V'},
+               {"help", no_argument, NULL, 'h'},
+               {NULL, 0, NULL, 0}
+       };
+
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);
-       atexit(close_stdout);
+       close_stdout_atexit();
 
        if (!strcmp(program_invocation_short_name, "vigr")) {
                program = VIGR;
@@ -325,23 +335,23 @@ int main(int argc, char *argv[])
                xstrncpy(orig_file, PASSWD_FILE, sizeof(orig_file));
        }
 
-       if (1 < argc) {
-               if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
-                       printf(UTIL_LINUX_VERSION);
-                       exit(EXIT_SUCCESS);
+       while ((c = getopt_long(argc, argv, "Vh", longopts, NULL)) != -1) {
+               switch (c) {
+               case 'V':
+                       print_version(EXIT_SUCCESS);
+               case 'h':
+                       usage();
+               default:
+                       errtryhelp(EXIT_FAILURE);
                }
-               if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help"))
-                       usage(stdout);
-               usage(stderr);
        }
 
        edit_file(0);
 
-       if (program == VIGR) {
-               strncpy(orig_file, SGROUP_FILE, FILENAMELEN - 1);
-       } else {
-               strncpy(orig_file, SHADOW_FILE, FILENAMELEN - 1);
-       }
+       if (program == VIGR)
+               xstrncpy(orig_file, SGROUP_FILE, sizeof(orig_file));
+       else
+               xstrncpy(orig_file, SHADOW_FILE, sizeof(orig_file));
 
        if (access(orig_file, F_OK) == 0) {
                char response[80];