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 
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 
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