Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "nsUserInfo.h"
7 : #include "nsCRT.h"
8 :
9 : #include <pwd.h>
10 : #include <sys/types.h>
11 : #include <unistd.h>
12 : #include <sys/utsname.h>
13 :
14 : #include "nsString.h"
15 : #include "nsXPIDLString.h"
16 : #include "nsReadableUtils.h"
17 : #include "nsNativeCharsetUtils.h"
18 :
19 : /* Some UNIXy platforms don't have pw_gecos. In this case we use pw_name */
20 : #if defined(NO_PW_GECOS)
21 : #define PW_GECOS pw_name
22 : #else
23 : #define PW_GECOS pw_gecos
24 : #endif
25 :
26 0 : nsUserInfo::nsUserInfo()
27 : {
28 0 : }
29 :
30 0 : nsUserInfo::~nsUserInfo()
31 : {
32 0 : }
33 :
34 0 : NS_IMPL_ISUPPORTS(nsUserInfo,nsIUserInfo)
35 :
36 : NS_IMETHODIMP
37 0 : nsUserInfo::GetFullname(char16_t **aFullname)
38 : {
39 0 : struct passwd *pw = nullptr;
40 :
41 0 : pw = getpwuid (geteuid());
42 :
43 0 : if (!pw || !pw->PW_GECOS) return NS_ERROR_FAILURE;
44 :
45 : #ifdef DEBUG_sspitzer
46 : printf("fullname = %s\n", pw->PW_GECOS);
47 : #endif
48 :
49 0 : nsAutoCString fullname(pw->PW_GECOS);
50 :
51 : // now try to parse the GECOS information, which will be in the form
52 : // Full Name, <other stuff> - eliminate the ", <other stuff>
53 : // also, sometimes GECOS uses "&" to mean "the user name" so do
54 : // the appropriate substitution
55 :
56 : // truncate at first comma (field delimiter)
57 : int32_t index;
58 0 : if ((index = fullname.Find(",")) != kNotFound)
59 0 : fullname.Truncate(index);
60 :
61 : // replace ampersand with username
62 0 : if (pw->pw_name) {
63 0 : nsAutoCString username(pw->pw_name);
64 0 : if (!username.IsEmpty() && nsCRT::IsLower(username.CharAt(0)))
65 0 : username.SetCharAt(nsCRT::ToUpper(username.CharAt(0)), 0);
66 :
67 0 : fullname.ReplaceSubstring("&", username.get());
68 : }
69 :
70 0 : nsAutoString unicodeFullname;
71 0 : NS_CopyNativeToUnicode(fullname, unicodeFullname);
72 :
73 0 : *aFullname = ToNewUnicode(unicodeFullname);
74 :
75 0 : if (*aFullname)
76 0 : return NS_OK;
77 :
78 0 : return NS_ERROR_FAILURE;
79 : }
80 :
81 : NS_IMETHODIMP
82 0 : nsUserInfo::GetUsername(char * *aUsername)
83 : {
84 0 : struct passwd *pw = nullptr;
85 :
86 : // is this portable? those are POSIX compliant calls, but I need to check
87 0 : pw = getpwuid(geteuid());
88 :
89 0 : if (!pw || !pw->pw_name) return NS_ERROR_FAILURE;
90 :
91 : #ifdef DEBUG_sspitzer
92 : printf("username = %s\n", pw->pw_name);
93 : #endif
94 :
95 0 : *aUsername = strdup(pw->pw_name);
96 :
97 0 : return NS_OK;
98 : }
99 :
100 : NS_IMETHODIMP
101 0 : nsUserInfo::GetDomain(char * *aDomain)
102 : {
103 0 : nsresult rv = NS_ERROR_FAILURE;
104 :
105 : struct utsname buf;
106 0 : char *domainname = nullptr;
107 :
108 0 : if (uname(&buf) < 0) {
109 0 : return rv;
110 : }
111 :
112 : #if defined(__linux__)
113 0 : domainname = buf.domainname;
114 : #endif
115 :
116 0 : if (domainname && domainname[0]) {
117 0 : *aDomain = strdup(domainname);
118 0 : rv = NS_OK;
119 : }
120 : else {
121 : // try to get the hostname from the nodename
122 : // on machines that use DHCP, domainname may not be set
123 : // but the nodename might.
124 0 : if (buf.nodename[0]) {
125 : // if the nodename is foo.bar.org, use bar.org as the domain
126 0 : char *pos = strchr(buf.nodename,'.');
127 0 : if (pos) {
128 0 : *aDomain = strdup(pos+1);
129 0 : rv = NS_OK;
130 : }
131 : }
132 : }
133 :
134 0 : return rv;
135 : }
136 :
137 : NS_IMETHODIMP
138 0 : nsUserInfo::GetEmailAddress(char * *aEmailAddress)
139 : {
140 : // use username + "@" + domain for the email address
141 :
142 : nsresult rv;
143 :
144 0 : nsAutoCString emailAddress;
145 0 : nsXPIDLCString username;
146 0 : nsXPIDLCString domain;
147 :
148 0 : rv = GetUsername(getter_Copies(username));
149 0 : if (NS_FAILED(rv)) return rv;
150 :
151 0 : rv = GetDomain(getter_Copies(domain));
152 0 : if (NS_FAILED(rv)) return rv;
153 :
154 0 : if (!username.IsEmpty() && !domain.IsEmpty()) {
155 0 : emailAddress = (const char *)username;
156 0 : emailAddress += "@";
157 0 : emailAddress += (const char *)domain;
158 : }
159 : else {
160 0 : return NS_ERROR_FAILURE;
161 : }
162 :
163 0 : *aEmailAddress = ToNewCString(emailAddress);
164 :
165 0 : return NS_OK;
166 : }
167 :
|