utils.c 5.72 KB
Newer Older
Warren Dukes's avatar
Warren Dukes committed
1
/* the Music Player Daemon (MPD)
2
 * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
Warren Dukes's avatar
Warren Dukes committed
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 * This project's homepage is: http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "utils.h"
20
#include "log.h"
21
#include "conf.h"
Max Kellermann's avatar
Max Kellermann committed
22 23

#include "../config.h"
Warren Dukes's avatar
Warren Dukes committed
24

Avuton Olrich's avatar
Avuton Olrich committed
25 26 27 28 29
char *myFgets(char *buffer, int bufferSize, FILE * fp)
{
	char *ret = fgets(buffer, bufferSize, fp);
	if (ret && strlen(buffer) > 0 && buffer[strlen(buffer) - 1] == '\n') {
		buffer[strlen(buffer) - 1] = '\0';
Warren Dukes's avatar
Warren Dukes committed
30
	}
Avuton Olrich's avatar
Avuton Olrich committed
31 32
	if (ret && strlen(buffer) > 0 && buffer[strlen(buffer) - 1] == '\r') {
		buffer[strlen(buffer) - 1] = '\0';
33
	}
Warren Dukes's avatar
Warren Dukes committed
34 35 36
	return ret;
}

Eric Wong's avatar
Eric Wong committed
37
char *string_toupper(char *str)
Avuton Olrich's avatar
Avuton Olrich committed
38
{
Eric Wong's avatar
Eric Wong committed
39 40
	int i = strlen(str);
	char *ret = str;
41

Eric Wong's avatar
Eric Wong committed
42 43
	for (; --i >= 0; ++str)
		*str = toupper((int)(*str));
44

Warren Dukes's avatar
Warren Dukes committed
45
	return ret;
Eric Wong's avatar
Eric Wong committed
46 47 48 49 50 51

}

char *strDupToUpper(char *str)
{
	return string_toupper(xstrdup(str));
Warren Dukes's avatar
Warren Dukes committed
52
}
53

Avuton Olrich's avatar
Avuton Olrich committed
54 55 56
void stripReturnChar(char *string)
{
	while (string && (string = strchr(string, '\n'))) {
57
		*string = ' ';
58 59
	}
}
60

Avuton Olrich's avatar
Avuton Olrich committed
61 62
void my_usleep(long usec)
{
63 64 65 66 67
	struct timeval tv;

	tv.tv_sec = 0;
	tv.tv_usec = usec;

Avuton Olrich's avatar
Avuton Olrich committed
68
	select(0, NULL, NULL, NULL, &tv);
69
}
70

Avuton Olrich's avatar
Avuton Olrich committed
71 72
int ipv6Supported(void)
{
73 74
#ifdef HAVE_IPV6
	int s;
Avuton Olrich's avatar
Avuton Olrich committed
75 76 77
	s = socket(AF_INET6, SOCK_STREAM, 0);
	if (s == -1)
		return 0;
78 79
	close(s);
	return 1;
80
#else
Avuton Olrich's avatar
Avuton Olrich committed
81
	return 0;
82
#endif
83 84
}

Avuton Olrich's avatar
Avuton Olrich committed
85 86
char *appendToString(char *dest, const char *src)
{
87 88 89
	int destlen;
	int srclen = strlen(src);

Avuton Olrich's avatar
Avuton Olrich committed
90
	if (dest == NULL) {
91
		dest = xmalloc(srclen + 1);
Avuton Olrich's avatar
Avuton Olrich committed
92
		memset(dest, 0, srclen + 1);
93
		destlen = 0;
Avuton Olrich's avatar
Avuton Olrich committed
94
	} else {
95
		destlen = strlen(dest);
96
		dest = xrealloc(dest, destlen + srclen + 1);
97 98
	}

Avuton Olrich's avatar
Avuton Olrich committed
99 100
	memcpy(dest + destlen, src, srclen);
	dest[destlen + srclen] = '\0';
101 102

	return dest;
103
}
104 105 106

unsigned long readLEuint32(const unsigned char *p)
{
Avuton Olrich's avatar
Avuton Olrich committed
107 108 109
	return ((unsigned long)p[0] << 0) |
	    ((unsigned long)p[1] << 8) |
	    ((unsigned long)p[2] << 16) | ((unsigned long)p[3] << 24);
110
}
111 112 113

mpd_malloc char *xstrdup(const char *s)
{
114
	char *ret = strdup(s);
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
	if (mpd_unlikely(!ret))
		FATAL("OOM: strdup\n");
	return ret;
}

/* borrowed from git :) */

mpd_malloc void *xmalloc(size_t size)
{
	void *ret;

	assert(mpd_likely(size));

	ret = malloc(size);
	if (mpd_unlikely(!ret))
		FATAL("OOM: malloc\n");
	return ret;
}

mpd_malloc void *xrealloc(void *ptr, size_t size)
{
Eric Wong's avatar
Eric Wong committed
136
	void *ret = realloc(ptr, size);
137

Eric Wong's avatar
Eric Wong committed
138 139 140 141 142
	/* some C libraries return NULL when size == 0,
	 * make sure we get a free()-able pointer (free(NULL)
	 * doesn't work with all C libraries, either) */
	if (mpd_unlikely(!ret && !size))
		ret = realloc(ptr, 1);
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

	if (mpd_unlikely(!ret))
		FATAL("OOM: realloc\n");
	return ret;
}

mpd_malloc void *xcalloc(size_t nmemb, size_t size)
{
	void *ret;

	assert(mpd_likely(nmemb && size));

	ret = calloc(nmemb, size);
	if (mpd_unlikely(!ret))
		FATAL("OOM: calloc\n");
	return ret;
}

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
char *parsePath(char *path)
{
	ConfigParam *param;
	struct passwd *passwd;
	char *newPath;
	char *c;
	int foundSlash = 0;
	int pos = 1;

	if (path[0] != '/' && path[0] != '~') {
		ERROR("\"%s\" is not an absolute path\n", path);
		return NULL;
	} else if (path[0] == '~') {
		if (path[1] == '/' || path[1] == '\0') {
			param = getConfigParam(CONF_USER);
			if (param && param->value) {
				passwd = getpwnam(param->value);
				if (!passwd) {
					ERROR("no such user %s\n",
				              param->value);
					return NULL;
				}
			} else {
				passwd = getpwuid(geteuid());
				if (!passwd) {
					ERROR("problems getting passwd entry "
					      "for current user\n");
					return NULL;
				}
			}
		} else {
			for (c = path + 1; *c != '\0' && *c != '/'; c++);
			if (*c == '/') {
				foundSlash = 1;
				*c = '\0';
			}
			pos = c - path;

			passwd = getpwnam(path + 1);
			if (!passwd) {
				ERROR("user \"%s\" not found\n", path + 1);
				return NULL;
			}

			if (foundSlash)
				*c = '/';
		}

		newPath = xmalloc(strlen(passwd->pw_dir) + strlen(path + pos) + 1);
		strcpy(newPath, passwd->pw_dir);
		strcat(newPath, path + pos);
	} else {
		newPath = xstrdup(path);
	}
215

216 217
	return newPath;
}
Eric Wong's avatar
Eric Wong committed
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232

int set_nonblocking(int fd)
{
	int ret, flags;

	assert(fd >= 0);

	while ((flags = fcntl(fd, F_GETFL)) < 0 && errno == EINTR) ;
	if (flags < 0)
		return flags;

	flags |= O_NONBLOCK;
	while ((ret = fcntl(fd, F_SETFL, flags)) < 0 && errno == EINTR) ;
	return ret;
}
233 234 235 236 237 238 239 240 241 242 243

void init_async_pipe(int file_des[2])
{
	if (pipe(file_des) < 0)
		FATAL("Couldn't open pipe: %s", strerror(errno));
	if (set_nonblocking(file_des[0]) < 0)
		FATAL("Couldn't set non-blocking I/O: %s\n", strerror(errno));
	if (set_nonblocking(file_des[1]) < 0)
		FATAL("Couldn't set non-blocking I/O: %s\n", strerror(errno));
}

244 245 246 247 248 249 250 251 252 253 254 255 256 257
void xpthread_mutex_init(pthread_mutex_t *m, const pthread_mutexattr_t *a)
{
	int err;
	if ((err = pthread_mutex_init(m, a)))
		FATAL("failed to init mutex: %s\n", strerror(err));
}

void xpthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a)
{
	int err;
	if ((err = pthread_cond_init(c, a)))
		FATAL("failed to init cond: %s\n", strerror(err));
}

258 259 260 261 262 263 264 265 266 267 268 269 270
void xpthread_mutex_destroy(pthread_mutex_t *mutex)
{
	int err;
	if ((err = pthread_mutex_destroy(mutex)))
		FATAL("failed to destroy mutex: %s\n", strerror(err));
}

void xpthread_cond_destroy(pthread_cond_t *cond)
{
	int err;
	if ((err = pthread_cond_destroy(cond)))
		FATAL("failed to destroy cond: %s\n", strerror(err));
}