]> code.delx.au - pulseaudio/blob - src/pulse/util.c
Merge commit 'elmarco/legacy-dir'
[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 pa_assert(p);
223
224 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
225 return fn+1;
226
227 return (char*) p;
228 }
229
230 char *pa_get_fqdn(char *s, size_t l) {
231 char hn[256];
232 #ifdef HAVE_GETADDRINFO
233 struct addrinfo *a, hints;
234 #endif
235
236 pa_assert(s);
237 pa_assert(l > 0);
238
239 if (!pa_get_host_name(hn, sizeof(hn)))
240 return NULL;
241
242 #ifdef HAVE_GETADDRINFO
243 memset(&hints, 0, sizeof(hints));
244 hints.ai_family = AF_UNSPEC;
245 hints.ai_flags = AI_CANONNAME;
246
247 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
248 return pa_strlcpy(s, hn, l);
249
250 pa_strlcpy(s, a->ai_canonname, l);
251 freeaddrinfo(a);
252 return s;
253 #else
254 return pa_strlcpy(s, hn, l);
255 #endif
256 }
257
258 int pa_msleep(unsigned long t) {
259 #ifdef OS_IS_WIN32
260 Sleep(t);
261 return 0;
262 #elif defined(HAVE_NANOSLEEP)
263 struct timespec ts;
264
265 ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
266 ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
267
268 return nanosleep(&ts, NULL);
269 #else
270 #error "Platform lacks a sleep function."
271 #endif
272 }