The directories in the
.B MOTD_FILE
are supported since version 2.36.
+.PP
+Note that
+.B login
+does not implement any filenames overriding behavior like pam_motd
+(see also MOTD_FIRSTONLY), but all content from all files is displayed. It is
+recommended to keep extra logic in content generators and use /run/motd.d rather
+than rely on overriding behavior hardcoded in system tools.
+.RE
+.PP
+.B MOTD_FIRSTONLY (boolean)
+.RS 4
+Forces
+.B login
+to stop display content specified by
+.B MOTD_FILE
+after first accessible item in the list. Note that a directory is one item in this case.
+This option allows to configure
+.B login
+semantic to be more compatible with pam_motd.
.RE
.PP
.B LOGIN_PLAIN_PROMPT
return 1; /* accept */
}
-static void motddir(const char *dirname)
+static int motddir(const char *dirname)
{
- int dd, nfiles, i;
+ int dd, nfiles, i, done = 0;
struct dirent **namelist = NULL;
dd = open(dirname, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
if (dd < 0)
- return;
+ return 0;
nfiles = scandirat(dd, ".", &namelist, motddir_filter, versionsort);
if (nfiles <= 0)
if (fstat(fd, &st) == 0 && st.st_size > 0)
sendfile(fileno(stdout), fd, NULL, st.st_size);
close(fd);
+ done++;
}
}
free(namelist);
done:
close(dd);
+ return done;
}
#endif /* MOTDDIR_SUPPORT */
{
const char *mb;
char *file, *list;
+ int firstonly, done = 0;
+
+ firstonly = getlogindefs_bool("MOTD_FIRSTONLY", 0);
mb = getlogindefs_str("MOTD_FILE", _PATH_MOTDFILE);
if (!mb || !*mb)
continue;
#ifdef MOTDDIR_SUPPORT
if (S_ISDIR(st.st_mode))
- motddir(file);
- else
+ done += motddir(file);
#endif
if (S_ISREG(st.st_mode) && st.st_size > 0) {
int fd = open(file, O_RDONLY, 0);
if (fd >= 0)
sendfile(fileno(stdout), fd, NULL, st.st_size);
close(fd);
+ done++;
}
+ if (firstonly && done)
+ break;
}
free(list);
}