]> code.delx.au - pulseaudio/blob - src/pulse/util.c
d561329cb70e9d25ccd628ddf41485df5e4268bd
[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
61 #include <pulsecore/core-error.h>
62 #include <pulsecore/log.h>
63 #include <pulsecore/core-util.h>
64
65 #include "util.h"
66
67 #ifndef OS_IS_WIN32
68 #define PATH_SEP '/'
69 #else
70 #define PATH_SEP '\\'
71 #endif
72
73 char *pa_get_user_name(char *s, size_t l) {
74 char *p;
75 char buf[1024];
76
77 #ifdef HAVE_PWD_H
78 struct passwd pw, *r;
79 #endif
80
81 assert(s && l > 0);
82
83 if (!(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) {
84 #ifdef HAVE_PWD_H
85
86 #ifdef HAVE_GETPWUID_R
87 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
88 #else
89 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
90 * that do not support getpwuid_r. */
91 if ((r = getpwuid(getuid())) == NULL) {
92 #endif
93 snprintf(s, l, "%lu", (unsigned long) getuid());
94 return s;
95 }
96
97 p = r->pw_name;
98
99 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
100 DWORD size = sizeof(buf);
101
102 if (!GetUserName(buf, &size))
103 return NULL;
104
105 p = buf;
106
107 #else /* HAVE_PWD_H */
108 return NULL;
109 #endif /* HAVE_PWD_H */
110 }
111
112 return pa_strlcpy(s, p, l);
113 }
114
115 char *pa_get_host_name(char *s, size_t l) {
116 assert(s && l > 0);
117 if (gethostname(s, l) < 0) {
118 pa_log("gethostname(): %s", pa_cstrerror(errno));
119 return NULL;
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 assert(s && l);
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 assert(s);
163 assert(l);
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 HAVE_READLINK
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 const char *pa_path_get_filename(const char *p) {
210 char *fn;
211
212 if ((fn = strrchr(p, PATH_SEP)))
213 return fn+1;
214
215 return (const char*) p;
216 }
217
218 char *pa_get_fqdn(char *s, size_t l) {
219 char hn[256];
220 #ifdef HAVE_GETADDRINFO
221 struct addrinfo *a, hints;
222 #endif
223
224 if (!pa_get_host_name(hn, sizeof(hn)))
225 return NULL;
226
227 #ifdef HAVE_GETADDRINFO
228 memset(&hints, 0, sizeof(hints));
229 hints.ai_family = AF_UNSPEC;
230 hints.ai_flags = AI_CANONNAME;
231
232 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
233 return pa_strlcpy(s, hn, l);
234
235 pa_strlcpy(s, a->ai_canonname, l);
236 freeaddrinfo(a);
237 return s;
238 #else
239 return pa_strlcpy(s, hn, l);
240 #endif
241 }
242
243 int pa_msleep(unsigned long t) {
244 #ifdef OS_IS_WIN32
245 Sleep(t);
246 return 0;
247 #elif defined(HAVE_NANOSLEEP)
248 struct timespec ts;
249
250 ts.tv_sec = t/1000;
251 ts.tv_nsec = (t % 1000) * 1000000;
252
253 return nanosleep(&ts, NULL);
254 #else
255 #error "Platform lacks a sleep function."
256 #endif
257 }