1 /* $NetBSD: fullname.c,v 1.1.1.1 2009/06/23 10:09:00 tron Exp $ */
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
fullname(void)54 const 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
main(int unused_argc,char ** unused_argv)105 int 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