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