]> code.delx.au - pulseaudio/blob - src/pulse/util.c
add a few more gcc warning flags and fix quite a few problems found by doing so
[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 errno = ENOENT;
100 return NULL;
101 }
102
103 p = buf;
104
105 #else /* HAVE_PWD_H */
106
107 return NULL;
108 #endif /* HAVE_PWD_H */
109 }
110
111 return pa_strlcpy(s, p, l);
112 }
113
114 char *pa_get_host_name(char *s, size_t l) {
115
116 pa_assert(s);
117 pa_assert(l > 0);
118
119 if (gethostname(s, l) < 0)
120 return NULL;
121
122 s[l-1] = 0;
123 return s;
124 }
125
126 char *pa_get_home_dir(char *s, size_t l) {
127 char *e;
128
129 #ifdef HAVE_PWD_H
130 char buf[1024];
131 struct passwd pw, *r;
132 #endif
133
134 pa_assert(s);
135 pa_assert(l > 0);
136
137 if ((e = getenv("HOME")))
138 return pa_strlcpy(s, e, l);
139
140 if ((e = getenv("USERPROFILE")))
141 return pa_strlcpy(s, e, l);
142
143 #ifdef HAVE_PWD_H
144
145 errno = 0;
146 #ifdef HAVE_GETPWUID_R
147 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
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 #endif
153 if (!errno)
154 errno = ENOENT;
155
156 return NULL;
157 }
158
159 return pa_strlcpy(s, r->pw_dir, l);
160 #else /* HAVE_PWD_H */
161
162 errno = ENOENT;
163 return NULL;
164 #endif
165 }
166
167 char *pa_get_binary_name(char *s, size_t l) {
168
169 pa_assert(s);
170 pa_assert(l > 0);
171
172 #if defined(OS_IS_WIN32)
173 {
174 char path[PATH_MAX];
175
176 if (GetModuleFileName(NULL, path, PATH_MAX))
177 return pa_strlcpy(s, pa_path_get_filename(path), l);
178 }
179 #endif
180
181 #ifdef __linux__
182 {
183 char *rp;
184 /* This works on Linux only */
185
186 if ((rp = pa_readlink("/proc/self/exe"))) {
187 pa_strlcpy(s, pa_path_get_filename(rp), l);
188 pa_xfree(rp);
189 return s;
190 }
191 }
192
193 #endif
194
195 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_GET_NAME)
196 {
197
198 #ifndef TASK_COMM_LEN
199 /* Actually defined in linux/sched.h */
200 #define TASK_COMM_LEN 16
201 #endif
202
203 char tcomm[TASK_COMM_LEN+1];
204 memset(tcomm, 0, sizeof(tcomm));
205
206 /* This works on Linux only */
207 if (prctl(PR_GET_NAME, (unsigned long) tcomm, 0, 0, 0) == 0)
208 return pa_strlcpy(s, tcomm, l);
209
210 }
211 #endif
212
213 errno = ENOENT;
214 return NULL;
215 }
216
217 char *pa_path_get_filename(const char *p) {
218 char *fn;
219
220 pa_assert(p);
221
222 if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
223 return fn+1;
224
225 return (char*) p;
226 }
227
228 char *pa_get_fqdn(char *s, size_t l) {
229 char hn[256];
230 #ifdef HAVE_GETADDRINFO
231 struct addrinfo *a, hints;
232 #endif
233
234 pa_assert(s);
235 pa_assert(l > 0);
236
237 if (!pa_get_host_name(hn, sizeof(hn)))
238 return NULL;
239
240 #ifdef HAVE_GETADDRINFO
241 memset(&hints, 0, sizeof(hints));
242 hints.ai_family = AF_UNSPEC;
243 hints.ai_flags = AI_CANONNAME;
244
245 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
246 return pa_strlcpy(s, hn, l);
247
248 pa_strlcpy(s, a->ai_canonname, l);
249 freeaddrinfo(a);
250 return s;
251 #else
252 return pa_strlcpy(s, hn, l);
253 #endif
254 }
255
256 int pa_msleep(unsigned long t) {
257 #ifdef OS_IS_WIN32
258 Sleep(t);
259 return 0;
260 #elif defined(HAVE_NANOSLEEP)
261 struct timespec ts;
262
263 ts.tv_sec = (time_t) (t/1000UL);
264 ts.tv_nsec = (long) ((t % 1000UL) * 1000000UL);
265
266 return nanosleep(&ts, NULL);
267 #else
268 #error "Platform lacks a sleep function."
269 #endif
270 }