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