1/*	$NetBSD$	*/
2
3/*++
4/* NAME
5/*	fullname 3
6/* SUMMARY
7/*	lookup personal name of invoking user
8/* SYNOPSIS
9/*	#include <fullname.h>
10/*
11/*	const char *fullname()
12/* DESCRIPTION
13/*	fullname() looks up the personal name of the invoking user.
14/*	The result is volatile. Make a copy if it is to be used for
15/*	an appreciable amount of time.
16/*
17/*	On UNIX systems, fullname() first tries to use the NAME environment
18/*	variable, provided that the environment can be trusted.
19/*	If that fails, fullname() extracts the username from the GECOS
20/*	field of the user's password-file entry, replacing any occurrence
21/*	of "&" by the login name, first letter capitalized.
22/*
23/*	A null result means that no full name information was found.
24/* SEE ALSO
25/*	safe_getenv(3) safe getenv() interface
26/* LICENSE
27/* .ad
28/* .fi
29/*	The Secure Mailer license must be distributed with this software.
30/* AUTHOR(S)
31/*	Wietse Venema
32/*	IBM T.J. Watson Research
33/*	P.O. Box 704
34/*	Yorktown Heights, NY 10598, USA
35/*--*/
36
37/* System library. */
38
39#include <sys_defs.h>
40#include <unistd.h>
41#include <pwd.h>
42#include <ctype.h>
43#include <stdlib.h>
44#include <string.h>
45
46/* Utility library. */
47
48#include "vstring.h"
49#include "safe.h"
50#include "fullname.h"
51
52/* fullname - get name of user */
53
54const char *fullname(void)
55{
56    static VSTRING *result;
57    char   *cp;
58    int     ch;
59    uid_t   uid;
60    struct passwd *pwd;
61
62    if (result == 0)
63	result = vstring_alloc(10);
64
65    /*
66     * Try the environment.
67     */
68    if ((cp = safe_getenv("NAME")) != 0)
69	return (vstring_str(vstring_strcpy(result, cp)));
70
71    /*
72     * Try the password file database.
73     */
74    uid = getuid();
75    if ((pwd = getpwuid(uid)) == 0)
76	return (0);
77
78    /*
79     * Replace all `&' characters by the login name of this user, first
80     * letter capitalized. Although the full name comes from the protected
81     * password file, the actual data is specified by the user so we should
82     * not trust its sanity.
83     */
84    VSTRING_RESET(result);
85    for (cp = pwd->pw_gecos; (ch = *(unsigned char *) cp) != 0; cp++) {
86	if (ch == ',' || ch == ';' || ch == '%')
87	    break;
88	if (ch == '&') {
89	    if (pwd->pw_name[0]) {
90		VSTRING_ADDCH(result, TOUPPER(pwd->pw_name[0]));
91		vstring_strcat(result, pwd->pw_name + 1);
92	    }
93	} else {
94	    VSTRING_ADDCH(result, ch);
95	}
96    }
97    VSTRING_TERMINATE(result);
98    return (vstring_str(result));
99}
100
101#ifdef TEST
102
103#include <stdio.h>
104
105int     main(int unused_argc, char **unused_argv)
106{
107    const char *cp = fullname();
108
109    printf("%s\n", cp ? cp : "null!");
110    return (0);
111}
112
113#endif
114