path.c revision 1.4
111568Sjkh/*	$OpenBSD: path.c,v 1.4 2015/01/16 16:18:07 deraadt Exp $	*/
211568Sjkh
311568Sjkh/*
411568Sjkh * Copyright (c) 2013 Kurt Miller <kurt@intricatesoftware.com>
511568Sjkh *
611568Sjkh * Permission to use, copy, modify, and distribute this software for any
711672Sjkh * purpose with or without fee is hereby granted, provided that the above
811568Sjkh * copyright notice and this permission notice appear in all copies.
911568Sjkh *
1011568Sjkh * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1111568Sjkh * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1211568Sjkh * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1311568Sjkh * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1411568Sjkh * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1511568Sjkh * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1611568Sjkh * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1711568Sjkh */
1811568Sjkh
1911568Sjkh#include <sys/types.h>
2011568Sjkh#include "path.h"
2111568Sjkh#include "util.h"
2211568Sjkh
2311568Sjkhchar **
2411568Sjkh_dl_split_path(const char *searchpath)
2511568Sjkh{
2611568Sjkh	int pos = 0;
2711568Sjkh	int count = 1;
2811568Sjkh	const char *pp, *p_begin;
2911568Sjkh	char **retval;
3011568Sjkh
3111568Sjkh	if (searchpath == NULL)
3211568Sjkh		return (NULL);
3311568Sjkh
3411568Sjkh	/* Count ':' or ';' in searchpath */
3511568Sjkh	pp = searchpath;
3611568Sjkh	while (*pp) {
3711568Sjkh		if (*pp == ':' || *pp == ';')
3811568Sjkh			count++;
3911568Sjkh		pp++;
4011568Sjkh	}
4111568Sjkh
4211568Sjkh	/* one more for NULL entry */
4311568Sjkh	count++;
4411568Sjkh
4511568Sjkh	retval = _dl_reallocarray(NULL, count, sizeof(retval));
4611568Sjkh	if (retval == NULL)
4711568Sjkh		return (NULL);
4811568Sjkh
4911568Sjkh	pp = searchpath;
5011568Sjkh	while (pp) {
5111568Sjkh		p_begin = pp;
5211568Sjkh		while (*pp != '\0' && *pp != ':' && *pp != ';')
5311568Sjkh			pp++;
5411568Sjkh
5511568Sjkh		/* interpret "" as curdir "." */
5611568Sjkh		if (p_begin == pp) {
5711568Sjkh			retval[pos] = _dl_malloc(2);
5811568Sjkh			if (retval[pos] == NULL)
5911568Sjkh				goto badret;
6011568Sjkh
6111568Sjkh			_dl_bcopy(".", retval[pos++], 2);
6211568Sjkh		} else {
6311568Sjkh			retval[pos] = _dl_malloc(pp - p_begin + 1);
6411568Sjkh			if (retval[pos] == NULL)
6511568Sjkh				goto badret;
6611672Sjkh
6711568Sjkh			_dl_bcopy(p_begin, retval[pos], pp - p_begin);
6811568Sjkh			retval[pos++][pp - p_begin] = '\0';
6911568Sjkh		}
7011568Sjkh
7111568Sjkh		if (*pp)        /* Try curdir if ':' at end */
7211568Sjkh			pp++;
7311568Sjkh		else
7411568Sjkh			pp = NULL;
7511568Sjkh	}
7611568Sjkh
7711568Sjkh	retval[pos] = NULL;
7811568Sjkh	return (retval);
7911568Sjkh
8011568Sjkhbadret:
8111568Sjkh	_dl_free_path(retval);
8211568Sjkh	return (NULL);
8311568Sjkh}
8411568Sjkh
8511568Sjkhvoid
8611568Sjkh_dl_free_path(char **path)
8711568Sjkh{
8811568Sjkh	char **p = path;
8911568Sjkh
9011568Sjkh	if (path == NULL)
9111568Sjkh		return;
9211568Sjkh
9311568Sjkh	while (*p != NULL)
9411568Sjkh		_dl_free(*p++);
9511568Sjkh
9611568Sjkh	_dl_free(path);
9711568Sjkh}
9811568Sjkh