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