+2007-12-26 Nicolas François <nicolas.francois@centraliens.net>
+
+ Merge Debian's patch 466_fflush-prompt
+ * libmisc/Makefile.am, lib/prototypes.h, libmisc/yesno.c, src/grpck.c,
+ src/pwck.c: move yes_or_no() from grpck/pwck to a separate
+ libmisc/yesno.c (with a read_only argument).
+ * libmisc/fields.c, libmisc/yesno.c: Make sure stdout is flushed before
+ reading the user's answer.
+
2007-12-26 Nicolas François <nicolas.francois@centraliens.net>
Merge Debian's patch 480_getopt_args_reorder
/* xgetspnam.c */
extern struct spwd *xgetspnam(const char *);
+/* yesno.c */
+extern int yes_or_no (int read_only);
+
#endif /* _PROTOTYPES_H */
xgetgrnam.c \
xgetgrgid.c \
xgetspnam.c \
- xmalloc.c
+ xmalloc.c \
+ yesno.c
maxsize = sizeof (newf);
printf ("\t%s [%s]: ", prompt, buf);
+ fflush (stdout);
if (fgets (newf, maxsize, stdin) != newf)
return;
--- /dev/null
+/*
+ * Copyright 1992 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Common code for yes/no prompting
+ *
+ * Used by pwck.c and grpck.c
+ */
+
+#include "config.h"
+
+#ident "$Id$"
+
+#include <stdio.h>
+#include "prototypes.h"
+
+/*
+ * yes_or_no - get answer to question from the user
+ *
+ * It returns 0 if no.
+ *
+ * If the read_only flag is set, it will print No, and will return 0.
+ */
+int yes_or_no (int read_only)
+{
+ char buf[80];
+
+ /*
+ * In read-only mode all questions are answered "no".
+ */
+ if (read_only) {
+ printf (_("No\n"));
+ return 0;
+ }
+
+ /*
+ * Typically, there's a prompt on stdout, sometimes unflushed.
+ */
+ fflush (stdout);
+
+ /*
+ * Get a line and see what the first character is.
+ */
+ /* TODO: use gettext */
+ if (fgets (buf, sizeof buf, stdin))
+ return buf[0] == 'y' || buf[0] == 'Y';
+
+ return 0;
+}
/* local function prototypes */
static void usage (void);
-static int yes_or_no (void);
static void delete_member (char **, const char *);
/*
exit (E_USAGE);
}
-/*
- * yes_or_no - get answer to question from the user
- */
-static int yes_or_no (void)
-{
- char buf[80];
-
- /*
- * In read-only mode all questions are answered "no".
- */
- if (read_only) {
- printf (_("No\n"));
- return 0;
- }
-
- /*
- * Get a line and see what the first character is.
- */
- if (fgets (buf, sizeof buf, stdin))
- return buf[0] == 'y' || buf[0] == 'Y';
-
- return 0;
-}
-
/*
* delete_member - delete an entry in a list of members
*/
/*
* prompt the user to delete the entry or not
*/
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
/*
/*
* prompt the user to delete the entry or not
*/
- if (yes_or_no ())
+ if (yes_or_no (read_only))
goto delete_gr;
}
grp->gr_name, grp->gr_mem[i]);
printf (_("delete member '%s'? "), grp->gr_mem[i]);
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
SYSLOG ((LOG_INFO, "delete member '%s' group '%s'",
printf (_("add group '%s' in %s ?"),
grp->gr_name, sgr_file);
errors++;
- if (yes_or_no ()) {
+ if (yes_or_no (read_only)) {
struct sgrp sg;
struct group gr;
static char *empty = NULL;
/*
* prompt the user to delete the entry or not
*/
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
/*
/*
* prompt the user to delete the entry or not
*/
- if (yes_or_no ())
+ if (yes_or_no (read_only))
goto delete_sg;
}
grp_file);
printf (_("delete line '%s'? "), sge->line);
errors++;
- if (yes_or_no ())
+ if (yes_or_no (read_only))
goto delete_sg;
} else {
/**
printf (_("delete administrative member '%s'? "),
sgr->sg_adm[i]);
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
SYSLOG ((LOG_INFO,
sgr->sg_name, sgr->sg_mem[i]);
printf (_("delete member '%s'? "), sgr->sg_mem[i]);
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
SYSLOG ((LOG_INFO,
/* local function prototypes */
static void usage (void);
-static int yes_or_no (void);
/*
* usage - print syntax message and exit
exit (E_USAGE);
}
-/*
- * yes_or_no - get answer to question from the user
- */
-static int yes_or_no (void)
-{
- char buf[80];
-
- /*
- * In read-only mode all questions are answered "no".
- */
-
- if (read_only) {
- printf (_("No\n"));
- return 0;
- }
-
- /*
- * Get a line and see what the first character is.
- */
- if (fgets (buf, sizeof buf, stdin))
- return buf[0] == 'y' || buf[0] == 'Y';
-
- return 0;
-}
-
/*
* pwck - verify password file integrity
*/
/*
* prompt the user to delete the entry or not
*/
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
/*
/*
* prompt the user to delete the entry or not
*/
- if (yes_or_no ())
+ if (yes_or_no (read_only))
goto delete_pw;
}
printf (_("add user '%s' in %s? "),
pwd->pw_name, spw_file);
errors++;
- if (yes_or_no ()) {
+ if (yes_or_no (read_only)) {
struct spwd sp;
struct passwd pw;
/*
* prompt the user to delete the entry or not
*/
- if (!yes_or_no ())
+ if (!yes_or_no (read_only))
continue;
/*
/*
* prompt the user to delete the entry or not
*/
- if (yes_or_no ())
+ if (yes_or_no (read_only))
goto delete_spw;
}
/*
* prompt the user to delete the entry or not
*/
- if (yes_or_no ())
+ if (yes_or_no (read_only))
goto delete_spw;
}