]> code.delx.au - pulseaudio/blob - src/pulse/util.c
merge 'lennart' branch back into trunk.
[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 <pulsecore/winsock.h>
59 #include <pulsecore/core-error.h>
60 #include <pulsecore/log.h>
61 #include <pulsecore/core-util.h>
62 #include <pulsecore/macro.h>
63
64 #include "util.h"
65
66 char *pa_get_user_name(char *s, size_t l) {
67 char *p;
68 char buf[1024];
69
70 #ifdef HAVE_PWD_H
71 struct passwd pw, *r;
72 #endif
73
74 pa_assert(s);
75 pa_assert(l > 0);
76
77 if (!(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) {
78 #ifdef HAVE_PWD_H
79
80 #ifdef HAVE_GETPWUID_R
81 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
82 #else
83 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
84 * that do not support getpwuid_r. */
85 if ((r = getpwuid(getuid())) == NULL) {
86 #endif
87 pa_snprintf(s, l, "%lu", (unsigned long) getuid());
88 return s;
89 }
90
91 p = r->pw_name;
92
93 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
94 DWORD size = sizeof(buf);
95
96 if (!GetUserName(buf, &size))
97 return NULL;
98
99 p = buf;
100
101 #else /* HAVE_PWD_H */
102 return NULL;
103 #endif /* HAVE_PWD_H */
104 }
105
106 return pa_strlcpy(s, p, l);
107 }
108
109 char *pa_get_host_name(char *s, size_t l) {
110
111 pa_assert(s);
112 pa_assert(l > 0);
113
114 if (gethostname(s, l) < 0) {
115 pa_log("gethostname(): %s", pa_cstrerror(errno));
116 return NULL;
117 }
118
119 s[l-1] = 0;
120 return s;
121 }
122
123 char *pa_get_home_dir(char *s, size_t l) {
124 char *e;
125
126 #ifdef HAVE_PWD_H
127 char buf[1024];
128 struct passwd pw, *r;
129 #endif
130
131 pa_assert(s);
132 pa_assert(l > 0);
133
134 if ((e = getenv("HOME")))
135 return pa_strlcpy(s, e, l);
136
137 if ((e = getenv("USERPROFILE")))
138 return pa_strlcpy(s, e, l);
139
140 #ifdef HAVE_PWD_H
141 #ifdef HAVE_GETPWUID_R
142 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
143 pa_log("getpwuid_r() failed");
144 #else
145 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
146 * that do not support getpwuid_r. */
147 if ((r = getpwuid(getuid())) == NULL) {
148 pa_log("getpwuid_r() failed");
149 #endif
150 return NULL;
151 }
152
153 return pa_strlcpy(s, r->pw_dir, l);
154 #else /* HAVE_PWD_H */
155 return NULL;
156 #endif
157 }
158
159 char *pa_get_binary_name(char *s, size_t l) {
160
161 pa_assert(s);
162 pa_assert(l > 0);
163
164 #if defined(OS_IS_WIN32)
165 {
166 char path[PATH_MAX];
167
168 if (GetModuleFileName(NULL, path, PATH_MAX))
169 return pa_strlcpy(s, pa_path_get_filename(path), l);
170 }
171 #endif
172
173 #ifdef __linux__
174 {
175 int i;
176 char path[PATH_MAX];
177 /* This works on Linux only */
178
179 if ((i = readlink("/proc/self/exe", path, sizeof(path)-1)) >= 0) {
180 path[i] = 0;
181 return pa_strlcpy(s, pa_path_get_filename(path), l);
182 }
183 }
184
185 #endif
186
187 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
188 {
189
190 #ifndef TASK_COMM_LEN
191 /* Actually defined in linux/sched.h */
192 #define TASK_COMM_LEN 16
193 #endif
194
195 char tcomm[TASK_COMM_LEN+1];
196 memset(tcomm, 0, sizeof(tcomm));
197
198 /* This works on Linux only */
199 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
200 return pa_strlcpy(s, tcomm, l);
201
202 }
203 #endif
204
205 return NULL;
206 }
207
208 char *pa_path_get_filename(const char *p) {
209 char *fn;
210
211 pa_assert(p);
212
213 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
214 return fn+1;
215
216 return (char*) p;
217 }
218
219 char *pa_get_fqdn(char *s, size_t l) {
220 char hn[256];
221 #ifdef HAVE_GETADDRINFO
222 struct addrinfo *a, hints;
223 #endif
224
225 pa_assert(s);
226 pa_assert(l > 0);
227
228 if (!pa_get_host_name(hn, sizeof(hn)))
229 return NULL;
230
231 #ifdef HAVE_GETADDRINFO
232 memset(&hints, 0, sizeof(hints));
233 hints.ai_family = AF_UNSPEC;
234 hints.ai_flags = AI_CANONNAME;
235
236 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
237 return pa_strlcpy(s, hn, l);
238
239 pa_strlcpy(s, a->ai_canonname, l);
240 freeaddrinfo(a);
241 return s;
242 #else
243 return pa_strlcpy(s, hn, l);
244 #endif
245 }
246
247 int pa_msleep(unsigned long t) {
248 #ifdef OS_IS_WIN32
249 Sleep(t);
250 return 0;
251 #elif defined(HAVE_NANOSLEEP)
252 struct timespec ts;
253
254 ts.tv_sec = t/1000;
255 ts.tv_nsec = (t % 1000) * 1000000;
256
257 return nanosleep(&ts, NULL);
258 #else
259 #error "Platform lacks a sleep function."
260 #endif
261 }