Back to index

lightning-sunbird  0.9+nobinonly
nsUserInfoUnix.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Seth Spitzer <sspitzer@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsUserInfo.h"
00040 #include "nsCRT.h"
00041 
00042 #include <pwd.h>
00043 #include <sys/types.h>
00044 #include <unistd.h>
00045 #include <sys/utsname.h>
00046 
00047 #include "nsString.h"
00048 #include "nsXPIDLString.h"
00049 #include "nsReadableUtils.h"
00050 
00051 /* Some UNIXy platforms don't have pw_gecos. In this case we use pw_name */
00052 #if defined(NO_PW_GECOS)
00053 #define PW_GECOS pw_name
00054 #else
00055 #define PW_GECOS pw_gecos
00056 #endif
00057 
00058 nsUserInfo::nsUserInfo()
00059 {
00060 }
00061 
00062 nsUserInfo::~nsUserInfo()
00063 {
00064 }
00065 
00066 NS_IMPL_ISUPPORTS1(nsUserInfo,nsIUserInfo)
00067 
00068 NS_IMETHODIMP
00069 nsUserInfo::GetFullname(PRUnichar **aFullname)
00070 {
00071     struct passwd *pw = nsnull;
00072 
00073     pw = getpwuid (geteuid());
00074 
00075     if (!pw || !pw->PW_GECOS) return NS_ERROR_FAILURE;
00076 
00077 #ifdef DEBUG_sspitzer
00078     printf("fullname = %s\n", pw->PW_GECOS);
00079 #endif
00080 
00081     nsCAutoString fullname(pw->PW_GECOS);
00082 
00083     // now try to parse the GECOS information, which will be in the form
00084     // Full Name, <other stuff> - eliminate the ", <other stuff>
00085     // also, sometimes GECOS uses "&" to mean "the user name" so do
00086     // the appropriate substitution
00087     
00088     // truncate at first comma (field delimiter)
00089     PRInt32 index;
00090     if ((index = fullname.Find(",")) != kNotFound)
00091         fullname.Truncate(index);
00092 
00093     // replace ampersand with username
00094     if (pw->pw_name) {
00095         nsCAutoString username(pw->pw_name);
00096         if (!username.IsEmpty() && nsCRT::IsLower(username.CharAt(0)))
00097             username.SetCharAt(nsCRT::ToUpper(username.CharAt(0)), 0);
00098             
00099         fullname.ReplaceSubstring("&", username.get());
00100     }
00101 
00102     *aFullname = ToNewUnicode(fullname);
00103 
00104     if (*aFullname)
00105         return NS_OK;
00106 
00107     return NS_ERROR_FAILURE;
00108 }
00109 
00110 NS_IMETHODIMP 
00111 nsUserInfo::GetUsername(char * *aUsername)
00112 {
00113     struct passwd *pw = nsnull;
00114 
00115     // is this portable?  those are POSIX compliant calls, but I need to check
00116     pw = getpwuid(geteuid());
00117 
00118     if (!pw || !pw->pw_name) return NS_ERROR_FAILURE;
00119 
00120 #ifdef DEBUG_sspitzer
00121     printf("username = %s\n", pw->pw_name);
00122 #endif
00123 
00124     *aUsername = nsCRT::strdup(pw->pw_name);
00125 
00126     return NS_OK;
00127 }
00128 
00129 NS_IMETHODIMP 
00130 nsUserInfo::GetDomain(char * *aDomain)
00131 {
00132     nsresult rv = NS_ERROR_FAILURE;
00133 
00134     struct utsname buf;
00135     char *domainname = nsnull;
00136 
00137     // is this portable?  that is a POSIX compliant call, but I need to check
00138     if (uname(&buf)) { 
00139         return rv;
00140     }
00141 
00142 #if defined(HAVE_UNAME_DOMAINNAME_FIELD)
00143     domainname = buf.domainname;
00144 #elif defined(HAVE_UNAME_US_DOMAINNAME_FIELD)
00145     domainname = buf.__domainname;
00146 #endif
00147 
00148     if (domainname && domainname[0]) {   
00149         *aDomain = nsCRT::strdup(domainname);
00150         rv = NS_OK;
00151     }
00152     else {
00153         // try to get the hostname from the nodename
00154         // on machines that use DHCP, domainname may not be set
00155         // but the nodename might.
00156         if (buf.nodename && buf.nodename[0]) {
00157             // if the nodename is foo.bar.org, use bar.org as the domain
00158             char *pos = strchr(buf.nodename,'.');
00159             if (pos) {
00160                 *aDomain = nsCRT::strdup(pos+1);
00161                 rv = NS_OK;
00162             }
00163         }
00164     }
00165     
00166     return rv;
00167 }
00168 
00169 NS_IMETHODIMP 
00170 nsUserInfo::GetEmailAddress(char * *aEmailAddress)
00171 {
00172     // use username + "@" + domain for the email address
00173 
00174     nsresult rv;
00175 
00176     nsCAutoString emailAddress;
00177     nsXPIDLCString username;
00178     nsXPIDLCString domain;
00179 
00180     rv = GetUsername(getter_Copies(username));
00181     if (NS_FAILED(rv)) return rv;
00182 
00183     rv = GetDomain(getter_Copies(domain));
00184     if (NS_FAILED(rv)) return rv;
00185 
00186     if (!username.IsEmpty() && !domain.IsEmpty()) {
00187         emailAddress = (const char *)username;
00188         emailAddress += "@";
00189         emailAddress += (const char *)domain;
00190     }
00191     else {
00192         return NS_ERROR_FAILURE;
00193     }
00194 
00195     *aEmailAddress = ToNewCString(emailAddress);
00196     
00197     return NS_OK;
00198 }
00199