summaryrefslogtreecommitdiffstats
path: root/login-utils/chsh.c
diff options
context:
space:
mode:
authorSami Kerola2014-12-14 23:50:44 +0100
committerSami Kerola2015-01-05 23:52:50 +0100
commit1cb122d5913e53338713ad3c4ff04b01e92725ac (patch)
treee9daae8b334547918a16533be2691c57cba9e63d /login-utils/chsh.c
parentchfn, chsh: share illegal_passwd_chars() function (diff)
downloadkernel-qcow2-util-linux-1cb122d5913e53338713ad3c4ff04b01e92725ac.tar.gz
kernel-qcow2-util-linux-1cb122d5913e53338713ad3c4ff04b01e92725ac.tar.xz
kernel-qcow2-util-linux-1cb122d5913e53338713ad3c4ff04b01e92725ac.zip
chsh: use getline() to support arbitrarily long lines
Use of fgets() can make a single long line to be understood as two entries, and someone could play tricks with the remainder part of the buffer. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'login-utils/chsh.c')
-rw-r--r--login-utils/chsh.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/login-utils/chsh.c b/login-utils/chsh.c
index 2245f4161..9ed4d06e5 100644
--- a/login-utils/chsh.c
+++ b/login-utils/chsh.c
@@ -87,8 +87,8 @@ static int get_shell_list(char *shell_name)
{
FILE *fp;
int found;
- int len;
- char buf[PATH_MAX];
+ char *buf = NULL;
+ size_t sz = 0, len;
found = false;
fp = fopen(_PATH_SHELLS, "r");
@@ -97,17 +97,17 @@ static int get_shell_list(char *shell_name)
warnx(_("No known shells."));
return true;
}
- while (fgets(buf, sizeof(buf), fp) != NULL) {
+ while (getline(&buf, &sz, fp) != -1) {
+ len = strlen(buf);
/* ignore comments */
if (*buf == '#')
continue;
- len = strlen(buf);
+ /* skip blank lines*/
+ if (len < 2)
+ continue;
/* strip the ending newline */
if (buf[len - 1] == '\n')
buf[len - 1] = 0;
- /* ignore lines that are too damn long */
- else
- continue;
/* check or output the shell */
if (shell_name) {
if (!strcmp(shell_name, buf)) {
@@ -118,6 +118,7 @@ static int get_shell_list(char *shell_name)
printf("%s\n", buf);
}
fclose(fp);
+ free(buf);
return found;
}