Git init
[framework/multimedia/pulseaudio.git] / 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 <pulse/timeval.h>
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 #include <pulsecore/usergroup.h>
65
66 #include "util.h"
67
68 char *pa_get_user_name(char *s, size_t l) {
69     const char *p;
70     char *name = NULL;
71 #ifdef OS_IS_WIN32
72     char buf[1024];
73 #endif
74
75 #ifdef HAVE_PWD_H
76     struct passwd *r;
77 #endif
78
79     pa_assert(s);
80     pa_assert(l > 0);
81
82     if ((p = (getuid() == 0 ? "root" : NULL)) ||
83         (p = getenv("USER")) ||
84         (p = getenv("LOGNAME")) ||
85         (p = getenv("USERNAME")))
86     {
87         name = pa_strlcpy(s, p, l);
88     } else {
89 #ifdef HAVE_PWD_H
90
91         if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
92             pa_snprintf(s, l, "%lu", (unsigned long) getuid());
93             return s;
94         }
95
96         name = pa_strlcpy(s, r->pw_name, l);
97         pa_getpwuid_free(r);
98
99 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
100         DWORD size = sizeof(buf);
101
102         if (!GetUserName(buf, &size)) {
103             errno = ENOENT;
104             return NULL;
105         }
106
107         name = pa_strlcpy(s, buf, l);
108
109 #else /* HAVE_PWD_H */
110
111         return NULL;
112 #endif /* HAVE_PWD_H */
113     }
114
115     return name;
116 }
117
118 char *pa_get_host_name(char *s, size_t l) {
119
120     pa_assert(s);
121     pa_assert(l > 0);
122
123     if (gethostname(s, l) < 0)
124         return NULL;
125
126     s[l-1] = 0;
127     return s;
128 }
129
130 char *pa_get_home_dir(char *s, size_t l) {
131     char *e, *dir;
132
133 #ifdef HAVE_PWD_H
134     struct passwd *r;
135 #endif
136
137     pa_assert(s);
138     pa_assert(l > 0);
139
140     if ((e = getenv("HOME")))
141         return pa_strlcpy(s, e, l);
142
143     if ((e = getenv("USERPROFILE")))
144         return pa_strlcpy(s, e, l);
145
146 #ifdef HAVE_PWD_H
147     errno = 0;
148     if ((r = pa_getpwuid_malloc(getuid())) == NULL) {
149         if (!errno)
150             errno = ENOENT;
151
152         return NULL;
153     }
154
155     dir = pa_strlcpy(s, r->pw_dir, l);
156
157     pa_getpwuid_free(r);
158
159     return dir;
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     if (!p)
221         return NULL;
222
223     if ((fn = strrchr(p, PA_PATH_SEP_CHAR)))
224         return fn+1;
225
226     return (char*) p;
227 }
228
229 char *pa_get_fqdn(char *s, size_t l) {
230     char hn[256];
231 #ifdef HAVE_GETADDRINFO
232     struct addrinfo *a, hints;
233 #endif
234
235     pa_assert(s);
236     pa_assert(l > 0);
237
238     if (!pa_get_host_name(hn, sizeof(hn)))
239         return NULL;
240
241 #ifdef HAVE_GETADDRINFO
242     memset(&hints, 0, sizeof(hints));
243     hints.ai_family = AF_UNSPEC;
244     hints.ai_flags = AI_CANONNAME;
245
246     if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
247         return pa_strlcpy(s, hn, l);
248
249     pa_strlcpy(s, a->ai_canonname, l);
250     freeaddrinfo(a);
251     return s;
252 #else
253     return pa_strlcpy(s, hn, l);
254 #endif
255 }
256
257 int pa_msleep(unsigned long t) {
258 #ifdef OS_IS_WIN32
259     Sleep(t);
260     return 0;
261 #elif defined(HAVE_NANOSLEEP)
262     struct timespec ts;
263
264     ts.tv_sec = (time_t) (t / PA_MSEC_PER_SEC);
265     ts.tv_nsec = (long) ((t % PA_MSEC_PER_SEC) * PA_NSEC_PER_MSEC);
266
267     return nanosleep(&ts, NULL);
268 #else
269 #error "Platform lacks a sleep function."
270 #endif
271 }