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