]> code.delx.au - pulseaudio/blob - src/pulse/util.c
Merge commit 'origin/master-tx'
[pulseaudio] / src / pulse / util.c
1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
11
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <errno.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <time.h>
33 #include <unistd.h>
34 #include <sys/types.h>
35
36 #ifdef HAVE_PWD_H
37 #include <pwd.h>
38 #endif
39
40 #ifdef HAVE_SYS_SOCKET_H
41 #include <sys/socket.h>
42 #endif
43
44 #ifdef HAVE_NETDB_H
45 #include <netdb.h>
46 #endif
47
48 #ifdef HAVE_WINDOWS_H
49 #include <windows.h>
50 #endif
51
52 #ifdef HAVE_SYS_PRCTL_H
53 #include <sys/prctl.h>
54 #endif
55
56 #include <pulse/xmalloc.h>
57 #include <pulse/timeval.h>
58
59 #include <pulsecore/winsock.h>
60 #include <pulsecore/core-error.h>
61 #include <pulsecore/log.h>
62 #include <pulsecore/core-util.h>
63 #include <pulsecore/macro.h>
64
65 #include "util.h"
66
67 char *pa_get_user_name(char *s, size_t l) {
68 const char *p;
69 char buf[1024];
70
71 #ifdef HAVE_PWD_H
72 struct passwd pw, *r;
73 #endif
74
75 pa_assert(s);
76 pa_assert(l > 0);
77
78 if (!(p = (getuid() == 0 ? "root" : NULL)) &&
79 !(p = getenv("USER")) &&
80 !(p = getenv("LOGNAME")) &&
81 !(p = getenv("USERNAME"))) {
82 #ifdef HAVE_PWD_H
83
84 #ifdef HAVE_GETPWUID_R
85 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
86 #else
87 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
88 * that do not support getpwuid_r. */
89 if ((r = getpwuid(getuid())) == NULL) {
90 #endif
91 pa_snprintf(s, l, "%lu", (unsigned long) getuid());
92 return s;
93 }
94
95 p = r->pw_name;
96
97 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
98 DWORD size = sizeof(buf);
99
100 if (!GetUserName(buf, &size)) {
101 errno = ENOENT;
102 return NULL;
103 }
104
105 p = buf;
106
107 #else /* HAVE_PWD_H */
108
109 return NULL;
110 #endif /* HAVE_PWD_H */
111 }
112
113 return pa_strlcpy(s, p, l);
114 }
115
116 char *pa_get_host_name(char *s, size_t l) {
117
118 pa_assert(s);
119 pa_assert(l > 0);
120
121 if (gethostname(s, l) < 0)
122 return NULL;
123
124 s[l-1] = 0;
125 return s;
126 }
127
128 char *pa_get_home_dir(char *s, size_t l) {
129 char *e;
130
131 #ifdef HAVE_PWD_H
132 char buf[1024];
133 struct passwd pw, *r;
134 #endif
135
136 pa_assert(s);
137 pa_assert(l > 0);
138
139 if ((e = getenv("HOME")))
140 return pa_strlcpy(s, e, l);
141
142 if ((e = getenv("USERPROFILE")))
143 return pa_strlcpy(s, e, l);
144
145 #ifdef HAVE_PWD_H
146
147 errno = 0;
148 #ifdef HAVE_GETPWUID_R
149 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
150 #else
151 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
152 * that do not support getpwuid_r. */
153 if ((r = getpwuid(getuid())) == NULL) {
154 #endif
155 if (!errno)
156 errno = ENOENT;
157
158 return NULL;
159 }
160
161 return pa_strlcpy(s, r->pw_dir, l);
162 #else /* HAVE_PWD_H */
163
164 errno = ENOENT;
165 return NULL;
166 #endif
167 }
168
169 char *pa_get_binary_name(char *s, size_t l) {
170
171 pa_assert(s);
172 pa_assert(l > 0);
173
174 #if defined(OS_IS_WIN32)
175 {
176 char path[PATH_MAX];
177
178 if (GetModuleFileName(NULL, path, PATH_MAX))
179 return pa_strlcpy(s, pa_path_get_filename(path), l);
180 }
181 #endif
182
183 #ifdef __linux__
184 {
185 char *rp;
186 /* This works on Linux only */
187
188 if ((rp = pa_readlink("/proc/self/exe"))) {
189 pa_strlcpy(s, pa_path_get_filename(rp), l);
190 pa_xfree(rp);
191 return s;
192 }
193 }
194
195 #endif
196
197 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
198 {
199
200 #ifndef TASK_COMM_LEN
201 /* Actually defined in linux/sched.h */
202 #define TASK_COMM_LEN 16
203 #endif
204
205 char tcomm[TASK_COMM_LEN+1];
206 memset(tcomm, 0, sizeof(tcomm));
207
208 /* This works on Linux only */
209 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
210 return pa_strlcpy(s, tcomm, l);
211
212 }
213 #endif
214
215 errno = ENOENT;
216 return NULL;
217 }
218
219 char *pa_path_get_filename(const char *p) {
220 char *fn;
221
222 if (!p)
223 return NULL;
224
225 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
226 return fn+1;
227
228 return (char*) p;
229 }
230
231 char *pa_get_fqdn(char *s, size_t l) {
232 char hn[256];
233 #ifdef HAVE_GETADDRINFO
234 struct addrinfo *a, hints;
235 #endif
236
237 pa_assert(s);
238 pa_assert(l > 0);
239
240 if (!pa_get_host_name(hn, sizeof(hn)))
241 return NULL;
242
243 #ifdef HAVE_GETADDRINFO
244 memset(&hints, 0, sizeof(hints));
245 hints.ai_family = AF_UNSPEC;
246 hints.ai_flags = AI_CANONNAME;
247
248 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
249 return pa_strlcpy(s, hn, l);
250
251 pa_strlcpy(s, a->ai_canonname, l);
252 freeaddrinfo(a);
253 return s;
254 #else
255 return pa_strlcpy(s, hn, l);
256 #endif
257 }
258
259 int pa_msleep(unsigned long t) {
260 #ifdef OS_IS_WIN32
261 Sleep(t);
262 return 0;
263 #elif defined(HAVE_NANOSLEEP)
264 struct timespec ts;
265
266 ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
267 ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
268
269 return nanosleep(&ts, NULL);
270 #else
271 #error "Platform lacks a sleep function."
272 #endif
273 }