]> code.delx.au - pulseaudio/blob - src/polyp/util.c
* split pa_cstrerror() into its own file polypcore/core-error.[ch]
[pulseaudio] / src / polyp / util.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
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 #include "../polypcore/winsock.h"
53
54 #include <polypcore/core-error.h>
55 #include <polypcore/log.h>
56 #include <polypcore/core-util.h>
57
58 #include "util.h"
59
60 #ifndef OS_IS_WIN32
61 #define PATH_SEP '/'
62 #else
63 #define PATH_SEP '\\'
64 #endif
65
66 char *pa_get_user_name(char *s, size_t l) {
67 char *p;
68 char buf[1024];
69
70 #ifdef HAVE_PWD_H
71 struct passwd pw, *r;
72 #endif
73
74 assert(s && l > 0);
75
76 if (!(p = getenv("USER")) && !(p = getenv("LOGNAME")) && !(p = getenv("USERNAME"))) {
77 #ifdef HAVE_PWD_H
78
79 #ifdef HAVE_GETPWUID_R
80 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
81 #else
82 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
83 * that do not support getpwuid_r. */
84 if ((r = getpwuid(getuid())) == NULL) {
85 #endif
86 snprintf(s, l, "%lu", (unsigned long) getuid());
87 return s;
88 }
89
90 p = r->pw_name;
91
92 #elif defined(OS_IS_WIN32) /* HAVE_PWD_H */
93 DWORD size = sizeof(buf);
94
95 if (!GetUserName(buf, &size))
96 return NULL;
97
98 p = buf;
99
100 #else /* HAVE_PWD_H */
101 return NULL;
102 #endif /* HAVE_PWD_H */
103 }
104
105 return pa_strlcpy(s, p, l);
106 }
107
108 char *pa_get_host_name(char *s, size_t l) {
109 assert(s && l > 0);
110 if (gethostname(s, l) < 0) {
111 pa_log(__FILE__": gethostname(): %s", pa_cstrerror(errno));
112 return NULL;
113 }
114 s[l-1] = 0;
115 return s;
116 }
117
118 char *pa_get_home_dir(char *s, size_t l) {
119 char *e;
120
121 #ifdef HAVE_PWD_H
122 char buf[1024];
123 struct passwd pw, *r;
124 #endif
125
126 assert(s && l);
127
128 if ((e = getenv("HOME")))
129 return pa_strlcpy(s, e, l);
130
131 if ((e = getenv("USERPROFILE")))
132 return pa_strlcpy(s, e, l);
133
134 #ifdef HAVE_PWD_H
135 #ifdef HAVE_GETPWUID_R
136 if (getpwuid_r(getuid(), &pw, buf, sizeof(buf), &r) != 0 || !r) {
137 pa_log(__FILE__": getpwuid_r() failed");
138 #else
139 /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X)
140 * that do not support getpwuid_r. */
141 if ((r = getpwuid(getuid())) == NULL) {
142 pa_log(__FILE__": getpwuid_r() failed");
143 #endif
144 return NULL;
145 }
146
147 return pa_strlcpy(s, r->pw_dir, l);
148 #else /* HAVE_PWD_H */
149 return NULL;
150 #endif
151 }
152
153 char *pa_get_binary_name(char *s, size_t l) {
154
155 #ifdef HAVE_READLINK
156 char path[PATH_MAX];
157 int i;
158 assert(s && l);
159
160 /* This works on Linux only */
161
162 snprintf(path, sizeof(path), "/proc/%u/exe", (unsigned) getpid());
163 if ((i = readlink(path, s, l-1)) < 0)
164 return NULL;
165
166 s[i] = 0;
167 return s;
168 #elif defined(OS_IS_WIN32)
169 char path[PATH_MAX];
170 if (!GetModuleFileName(NULL, path, PATH_MAX))
171 return NULL;
172 pa_strlcpy(s, pa_path_get_filename(path), l);
173 return s;
174 #else
175 return NULL;
176 #endif
177 }
178
179 const char *pa_path_get_filename(const char *p) {
180 char *fn;
181
182 if ((fn = strrchr(p, PATH_SEP)))
183 return fn+1;
184
185 return (const char*) p;
186 }
187
188 char *pa_get_fqdn(char *s, size_t l) {
189 char hn[256];
190 #ifdef HAVE_GETADDRINFO
191 struct addrinfo *a, hints;
192 #endif
193
194 if (!pa_get_host_name(hn, sizeof(hn)))
195 return NULL;
196
197 #ifdef HAVE_GETADDRINFO
198 memset(&hints, 0, sizeof(hints));
199 hints.ai_family = AF_UNSPEC;
200 hints.ai_flags = AI_CANONNAME;
201
202 if (getaddrinfo(hn, NULL, &hints, &a) < 0 || !a || !a->ai_canonname || !*a->ai_canonname)
203 return pa_strlcpy(s, hn, l);
204
205 pa_strlcpy(s, a->ai_canonname, l);
206 freeaddrinfo(a);
207 return s;
208 #else
209 return pa_strlcpy(s, hn, l);
210 #endif
211 }
212
213 int pa_msleep(unsigned long t) {
214 #ifdef OS_IS_WIN32
215 Sleep(t);
216 return 0;
217 #elif defined(HAVE_NANOSLEEP)
218 struct timespec ts;
219
220 ts.tv_sec = t/1000;
221 ts.tv_nsec = (t % 1000) * 1000000;
222
223 return nanosleep(&ts, NULL);
224 #else
225 #error "Platform lacks a sleep function."
226 #endif
227 }