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