.\" SUCH DAMAGE.
.\"
.\" @(#)fingerd.8 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/libexec/fingerd/fingerd.8,v 1.4.2.3 2001/08/16 10:44:15 ru Exp $
+.\" $FreeBSD: src/libexec/fingerd/fingerd.8,v 1.14 2005/01/18 09:29:39 ru Exp $
.\" $DragonFly: src/libexec/fingerd/fingerd.8,v 1.5 2007/11/23 23:16:36 swildner Exp $
.\"
.Dd June 4, 1993
.Op Fl l
.Op Fl p Ar filename
.Sh DESCRIPTION
-.Nm Fingerd
-is a simple protocol based on
+The
+.Nm
+utility uses a simple protocol based on
.%T RFC 1196
-that provides an interface to the
-Name and Finger programs at several network sites.
-The program is supposed to return a friendly,
+that provides an interface to
+.Xr finger 1
+at several network sites.
+It is supposed to return a friendly,
human-oriented status report on either the system at the moment
or a particular person in depth.
There is no required format and the
protocol consists mostly of specifying a single
-.Dq command line .
+.Dq "command line" ,
+thus,
+.Nm
+can also be used to implement other protocols in conjunction with the
+.Fl p
+flag.
.Pp
-.Nm Fingerd
-is started by
+The
+.Nm
+utility is started by
.Xr inetd 8 ,
which listens for
.Tn TCP
.Aq Tn CRLF
which is passed to
.Xr finger 1 .
-.Nm Fingerd
-closes its connections as soon as the output is finished.
+The
+.Nm
+utility closes its connections as soon as the output is finished.
.Pp
-If the line is null (i.e. just a
+If the line is null (i.e., just a
.Aq Tn CRLF
is sent) then
.Xr finger 1
this option allows a system manager
to have more control over what information is
provided to remote sites.
+If
+.Fl p
+is specified,
+.Nm
+will also set the environment variable
+.Ev FINGERD_REMOTE_HOST
+to the name of the host making the request.
.El
.Sh SEE ALSO
.Xr finger 1 ,
.Sh HISTORY
The
.Nm
-command appeared in
+utility appeared in
.Bx 4.3 .
.Sh BUGS
Connecting directly to the server from a
user program can result
in meaningless attempts at option negotiation being sent to the
server, which will foul up the command line interpretation.
-.Nm Fingerd
-should be taught to filter out
+The
+.Nm
+utility should be taught to filter out
.Tn IAC Ns \'s
and perhaps even respond
negatively
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * @(#) Copyright (c) 1983, 1993 The Regents of the University of California. All rights reserved.
* @(#)fingerd.c 8.1 (Berkeley) 6/4/93
- * $FreeBSD: src/libexec/fingerd/fingerd.c,v 1.16.2.3 2002/04/03 09:05:23 mike Exp $
+ * $FreeBSD: src/libexec/fingerd/fingerd.c,v 1.26 2008/08/04 01:25:48 cperciva Exp $
* $DragonFly: src/libexec/fingerd/fingerd.c,v 1.3 2003/11/14 03:54:29 dillon Exp $
*/
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
-#include <strings.h>
+#include <string.h>
#include "pathnames.h"
-void logerr (const char *, ...);
+void logerr(const char *, ...) __printflike(1, 2) __dead2;
int
-main(argc, argv)
- int argc;
- char *argv[];
+main(int argc, char *argv[])
{
- register FILE *fp;
- register int ch;
- register char *lp;
+ FILE *fp;
+ int ch;
+ char *lp;
struct sockaddr_storage ss;
- int p[2], logging, secure, sval;
+ socklen_t sval;
+ int p[2], logging, pflag, secure;
#define ENTRIES 50
char **ap, *av[ENTRIES + 1], **comp, line[1024], *prog;
char rhost[MAXHOSTNAMELEN];
prog = _PATH_FINGER;
- logging = secure = 0;
+ logging = pflag = secure = 0;
openlog("fingerd", LOG_PID | LOG_CONS, LOG_DAEMON);
opterr = 0;
- while ((ch = getopt(argc, argv, "slp:")) != -1)
+ while ((ch = getopt(argc, argv, "lp:s")) != -1)
switch (ch) {
case 'l':
logging = 1;
break;
case 'p':
prog = optarg;
+ pflag = 1;
break;
case 's':
secure = 1;
if (!fgets(line, sizeof(line), stdin))
exit(1);
+ if (logging || pflag) {
+ sval = sizeof(ss);
+ if (getpeername(0, (struct sockaddr *)&ss, &sval) < 0)
+ logerr("getpeername: %s", strerror(errno));
+ realhostname_sa(rhost, sizeof rhost - 1,
+ (struct sockaddr *)&ss, sval);
+ rhost[sizeof(rhost) - 1] = '\0';
+ if (pflag)
+ setenv("FINGERD_REMOTE_HOST", rhost, 1);
+ }
+
if (logging) {
char *t;
char *end;
for (end = t; *end; end++)
if (*end == '\n' || *end == '\r')
*end = ' ';
- sval = sizeof(ss);
- if (getpeername(0, (struct sockaddr *)&ss, &sval) < 0)
- logerr("getpeername: %s", strerror(errno));
- realhostname_sa(rhost, sizeof rhost - 1,
- (struct sockaddr *)&ss, sval);
- rhost[sizeof(rhost) - 1] = '\0';
syslog(LOG_NOTICE, "query from %s: `%s'", rhost, t);
}
lp = NULL;
}
- if (lp = strrchr(prog, '/'))
+ if ((lp = strrchr(prog, '/')) != NULL)
*comp = ++lp;
else
*comp = prog;
switch(vfork()) {
case 0:
- (void)close(p[0]);
- if (p[1] != 1) {
- (void)dup2(p[1], 1);
- (void)close(p[1]);
+ close(p[0]);
+ if (p[1] != STDOUT_FILENO) {
+ dup2(p[1], STDOUT_FILENO);
+ close(p[1]);
}
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+
execv(prog, comp);
- logerr("execv: %s: %s", prog, strerror(errno));
+ write(STDERR_FILENO, prog, strlen(prog));
+#define MSG ": cannot execute\n"
+ write(STDERR_FILENO, MSG, strlen(MSG));
+#undef MSG
_exit(1);
case -1:
logerr("fork: %s", strerror(errno));
}
- (void)close(p[1]);
+ close(p[1]);
if (!(fp = fdopen(p[0], "r")))
logerr("fdopen: %s", strerror(errno));
while ((ch = getc(fp)) != EOF) {
exit(0);
}
-#if __STDC__
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
void
-#if __STDC__
logerr(const char *fmt, ...)
-#else
-logerr(fmt, va_alist)
- char *fmt;
- va_dcl
-#endif
{
va_list ap;
-#if __STDC__
va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- (void)vsyslog(LOG_ERR, fmt, ap);
+ vsyslog(LOG_ERR, fmt, ap);
va_end(ap);
exit(1);
/* NOTREACHED */