summaryrefslogtreecommitdiffstats
path: root/po/bn.po
Commit message (Expand)AuthorAgeFilesLines
* s/Mandrake/Mandriva/Pablo Saratxaga2005-04-251-12/+12
* Merge stringsRafael Garcia-Suarez2005-04-211-11/+10
* merge new stringsRafael Garcia-Suarez2005-04-211-302/+316
* Better explanation for the --noclean urpmi optionRafael Garcia-Suarez2005-04-211-1/+1
* English grammar fixRafael Garcia-Suarez2005-04-111-1/+1
* Better wording for "wrote config file" message (bug 14312)Rafael Garcia-Suarez2005-04-111-1/+1
* Misformatted error messageRafael Garcia-Suarez2005-02-171-2/+2
* Fix English grammarRafael Garcia-Suarez2005-02-151-1/+1
* updated po filePablo Saratxaga2005-02-131-147/+168
* updated pot filePablo Saratxaga2005-02-031-42/+42
* Updated POT.Funda Wang2005-01-311-189/+192
* updated pot filePablo Saratxaga2005-01-201-50/+65
* Merge po filesRafael Garcia-Suarez2005-01-191-192/+192
* rescued some translationsPablo Saratxaga2005-01-061-114/+67
* Merge new stringsRafael Garcia-Suarez2005-01-061-102/+234
* Update copyright stringsRafael Garcia-Suarez2005-01-061-2/+2
* updated pot filePablo Saratxaga2005-01-031-341/+349
* updated pot filePablo Saratxaga2004-11-261-246/+263
* updated pot filePablo Saratxaga2004-11-221-159/+168
* updated pot filePablo Saratxaga2004-11-091-125/+121
* updated pot filePablo Saratxaga2004-11-041-80/+85
* Change an English message to be more descriptive.Rafael Garcia-Suarez2004-11-021-1/+1
* updated pot filePablo Saratxaga2004-10-261-141/+146
* updated pot filePablo Saratxaga2004-10-151-263/+290
* Fix two English messagesRafael Garcia-Suarez2004-10-141-2/+2
* updated po filesPablo Saratxaga2004-09-071-93/+69
* updated pot filePablo Saratxaga2004-08-271-0/+2128
ref='#n230'>230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
/*
 * dietlibc/libshell/glob.c
 *
 * Copyright 2001 Guillaume Cottenceau <gc@mandrakesoft.com>
 *
 * This is free software, licensed under the Gnu General Public License.
 *
 */

/*
 * unsupported: GLOB_BRACE GLOB_ALTDIRFUNC GLOB_MAGCHAR
 */

#define DEBUG(x)

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <fnmatch.h>
#include <dirent.h>
#include <pwd.h>

#include <glob.h>



/* If i18n, should be using strcoll */
static int cmp_func(const void * a, const void * b)
{
	const char *const s1 = *(const char *const * const) a;
	const char *const s2 = *(const char *const * const) b;
	if (s1 == NULL)
		return 1;
	if (s2 == NULL)
		return -1;
	return strcmp(s1, s2);
}


/* Like `glob', but PATTERN is a final pathname component,
   and matches are searched for in DIRECTORY.
   The GLOB_NOSORT bit in FLAGS is ignored.  No sorting is ever done.
   The GLOB_APPEND flag is assumed to be set (always appends).
   Prepends DIRECTORY in constructed PGLOB. */
static int glob_in_dir(const char *pattern, const char *directory, int flags,
		       int errfunc(const char * epath, int eerrno),
		       glob_t *pglob)
{
	DIR *dp = opendir(directory);
	int nfound = 0;

	int i;
	char * ptr;

	void close_dir_keep_errno(void) {
		int save = errno;
		if (dp)
			closedir (dp);
		__set_errno(save);
	}
	int add_entry(const char * name) {
		pglob->gl_pathv	= (char **) realloc(pglob->gl_pathv,
						    (pglob->gl_pathc + pglob->gl_offs + 2)
						    * sizeof (char *));
		if (pglob->gl_pathv == NULL)
			return 1;
		pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = strdup(name);
		pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc + 1] = NULL;
		pglob->gl_pathc++;
		nfound++;
		return 0;
	}
	void build_fullname(char * fullname, int fullnamesize, const char * directory, const char * filename) {
		if (!strcmp(directory, "/"))
			snprintf(fullname, fullnamesize, "/%s", filename);
		else if (!strcmp(directory, "."))
			snprintf(fullname, fullnamesize, "%s", filename);
		else
			snprintf(fullname, fullnamesize, "%s/%s", directory, filename);
	}

	if (!dp) {
		if (errno != ENOTDIR
		    && ((errfunc != NULL && (*errfunc) (directory, errno))
			|| (flags & GLOB_ERR)))
		      return GLOB_ABORTED;
	} else {
		int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
				 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0));
		struct dirent *ep;
		while ((ep = readdir(dp))) {
			i = strlen(directory) + strlen(ep->d_name) + 2;
			ptr = (char *) alloca(i);
			build_fullname(ptr, i, directory, ep->d_name);
			if (flags & GLOB_ONLYDIR) {
				struct stat statr;
				if (stat(ptr, &statr) || !S_ISDIR(statr.st_mode))
					continue;
			}
			if (fnmatch(pattern, ep->d_name, fnm_flags) == 0)
				if (add_entry(ptr))
					goto memory_error;
		}
	}

	close_dir_keep_errno();

	if (nfound != 0)
		pglob->gl_flags = flags;
	else if (flags & GLOB_NOCHECK) {
		/* nfound == 0 */
		i = strlen(directory) + strlen(pattern) + 2;
		ptr = (char *) alloca(i);
		build_fullname(ptr, i, directory, pattern);
		if (add_entry(ptr))
			goto memory_error;
	}

	return (nfound == 0) ? GLOB_NOMATCH : 0;

 memory_error:
	/* We're in trouble since we can't free the already allocated memory. [allocated from strdup(filame)]
	 * Well, after all, when malloc returns NULL we're already in a bad mood, and no doubt the
	 * program will manage to segfault by itself very soon :-). */
	close_dir_keep_errno();
	return GLOB_NOSPACE;
}



int glob(const char *pattern, int flags, int errfunc(const char * epath, int eerrno), glob_t *pglob)
{
	char * pattern_;
	char * filename;
	char * dirname;
	size_t oldcount;
	struct stat statr;

	size_t i; /* tmp variables are declared here to save a bit of object space */
	int j, k;    /* */
	char * ptr, * ptr2;

	if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) {
		__set_errno (EINVAL);
		return -1;
	}

	if (!(flags & GLOB_DOOFFS))
		pglob->gl_offs = 0;


	/* Duplicate pattern so I can make modif to it later (to handle
           TILDE stuff replacing old contents, and to null-terminate the
           directory) */
	pattern_ = alloca(strlen(pattern) + 1);
	strcpy(pattern_, pattern);

	/* Check for TILDE stuff */
	if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern_[0] == '~') {
		char * home_dir = NULL;
		if (pattern_[1] == '\0' || pattern_[1] == '/') {
			/* She's asking for ~, her homedir */
			home_dir = getenv("HOME");
		} else {
			/* She's asking for another one's homedir */
			struct passwd * p;
			ptr2 = alloca(strlen(pattern_) + 1);
			strcpy(ptr2, pattern_ + 1);
			ptr = strchr(ptr2, '/');
			if (ptr != NULL)
				*ptr = '\0';
			if (((p = getpwnam(ptr2)) != NULL))
				home_dir = p->pw_dir;
		}
		if (home_dir != NULL) {
			i = strlen(home_dir) + strlen(pattern_); /* pessimistic (the ~ case) */
			ptr = alloca(i);
			strncpy(ptr, home_dir, i);
			ptr2 = pattern_ + 1;
			while (*ptr2 != '/' && *ptr2 != '\0')
				ptr2++;
			strncat(ptr, ptr2, i);
			pattern_ = ptr;
		} else if (flags & GLOB_TILDE_CHECK)
			return GLOB_NOMATCH;
	}

	/* Find the filename */
	filename = strrchr(pattern_, '/');

	if (filename == NULL) {
		/* We have no '/' in the pattern */
		filename = pattern_;
		dirname = ".";
	} else if (filename == pattern_) {
		/* "/pattern".  */
		dirname = "/";
		filename++;
	} else {
		dirname = pattern_;
		filename++;
		/* allow dirname to be null terminated */
		*(filename-1) = '\0';

		if (filename[0] == '\0' && strcmp(pattern_, "/")) {
			/* "pattern/".  Expand "pattern", appending slashes.  */
			j = glob(dirname, flags | GLOB_MARK, errfunc, pglob);
			if (j == 0)
				pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
						   | (flags & GLOB_MARK));
			return j;
		}
	}

	
	/* Reserve memory for pglob */
	if (!(flags & GLOB_APPEND)) {
		pglob->gl_pathc = 0;
		if (!(flags & GLOB_DOOFFS))
			pglob->gl_pathv = NULL;
		else {
			pglob->gl_pathv = (char **) malloc((pglob->gl_offs + 1) * sizeof (char *));
			if (pglob->gl_pathv == NULL)
				return GLOB_NOSPACE;
			for (i = 0; i <= pglob->gl_offs; i++)
				pglob->gl_pathv[i] = NULL;
		}
	}


	oldcount = pglob->gl_pathc + pglob->gl_offs;


	/* Begin real work */
	if (!strcmp(dirname, "/") || !strcmp(dirname, ".")
	    || (!strchr(dirname, '*') && !strchr(dirname, '?') && !strchr(dirname, '['))) {
		/* Approx of a terminal state, glob directly in dir. */
		j = glob_in_dir(filename, dirname, flags, errfunc, pglob);
		if (j != 0)
			return j;
	} else {
		/* We are not in a terminal state, so we have to glob for
		   the directory, and then glob for the pattern in each
		   directory found. */
		glob_t dirs;

		j = glob(dirname, ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ALTDIRFUNC))
				   | GLOB_NOSORT | GLOB_ONLYDIR),
			 errfunc, &dirs);
		if (j != 0)
			return j;

		/* We have successfully globbed the directory name.
		   For each name we found, call glob_in_dir on it and FILENAME,
		   appending the results to PGLOB.  */
		for (i = 0; i < dirs.gl_pathc; i++) {
			j = glob_in_dir(filename, dirs.gl_pathv[i], ((flags | GLOB_APPEND) & ~GLOB_NOCHECK),
					errfunc, pglob);
			if (j == GLOB_NOMATCH)
				/* No matches in this directory.  Try the next.  */
				continue;
			if (j != 0) {
				globfree(&dirs);
				globfree(pglob);
				return j;
			}
		}

		/* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
		   But if we have not found any matching entry and the GLOB_NOCHECK
		   flag was set we must return the list consisting of the disrectory
		   names followed by the filename.  */
		if (pglob->gl_pathc + pglob->gl_offs == oldcount)
		{
			/* No matches.  */
			if (flags & GLOB_NOCHECK)
			{
				for (i = 0; i < dirs.gl_pathc; i++) {
					if (stat(dirs.gl_pathv[i], &statr) || !S_ISDIR(statr.st_mode))
						continue;

					/* stat is okay, we will add the entry, but before let's resize the pathv */
					j = pglob->gl_pathc + pglob->gl_offs;
					pglob->gl_pathv = (char **) realloc(pglob->gl_pathv, (j + 2) * sizeof (char *));
					if (pglob->gl_pathv == NULL) {
						globfree (&dirs);
						return GLOB_NOSPACE;
					}

					/* okay now we add the new entry */
					k = strlen(dirs.gl_pathv[i]) + 1 + strlen(filename) + 1;
					if ((pglob->gl_pathv[j] = malloc(k)) == NULL) {
						globfree(&dirs);
						globfree(pglob);
						return GLOB_NOSPACE;
					}
					snprintf(pglob->gl_pathv[j], k, "%s/%s", dirs.gl_pathv[i], filename);
					pglob->gl_pathc++;
					pglob->gl_pathv[j+1] = NULL;
				}
			} else {
				globfree(&dirs);
				return GLOB_NOMATCH;
			}
		}

		globfree (&dirs);
	}


	if (flags & GLOB_MARK) {
		for (i = oldcount; i < pglob->gl_pathc + pglob->gl_offs; i++)
			if (!stat(pglob->gl_pathv[i], &statr) && S_ISDIR(statr.st_mode)) {
				size_t len = strlen(pglob->gl_pathv[i]) + 2;
				ptr = realloc(pglob->gl_pathv[i], len);
				if (ptr == NULL) {
					globfree(pglob);
					return GLOB_NOSPACE;
				}
				strcpy(&ptr[len - 2], "/");
				pglob->gl_pathv[i] = ptr;
			}
	}

	if (!(flags & GLOB_NOSORT)) {
		qsort(&pglob->gl_pathv[oldcount],
		      pglob->gl_pathc + pglob->gl_offs - oldcount,
		      sizeof(char *), cmp_func);
	}

	return 0;
}


/* Free storage allocated in PGLOB by a previous `glob' call.  */
void globfree (glob_t * pglob)
{
  if (pglob->gl_pathv != NULL) {
      size_t i;
      for (i = 0; i < pglob->gl_pathc; i++)
	      if (pglob->gl_pathv[pglob->gl_offs + i] != NULL)
		      free((void *) pglob->gl_pathv[pglob->gl_offs + i]);
      free((void *) pglob->gl_pathv);
  }
}