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