glob.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/****************************************************************************
Copyright (c) 1999,2000,2001 WU-FTPD Development Group.
All rights reserved.
Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994
The Regents of the University of California.
Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.
Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.
Portions Copyright (c) 1989 Massachusetts Institute of Technology.
Portions Copyright (c) 1998 Sendmail, Inc.
Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman.
Portions Copyright (c) 1997 by Stan Barber.
Portions Copyright (c) 1997 by Kent Landfield.
Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
Use and distribution of this software and its source code are governed
by the terms and conditions of the WU-FTPD Software License ("LICENSE").
If you did not receive a copy of the license, it may be obtained online
$Id: glob.c,v 1.14.2.2 2001/11/29 17:01:38 wuftpd Exp $
****************************************************************************/
/*
* C-shell glob for random programs.
*/
#include "config.h"
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#else
#endif
#include <pwd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "proto.h"
#define QUOTE 0200
#define TRIM 0177
static char **gargv; /* Pointer to the (stack) arglist */
static char **agargv;
static size_t agargv_size;
static int gargc; /* Number args in gargv */
static short gflag;
static int tglob(register char);
/* Prototypes */
static char *strend(register char *);
static void addpath(char);
static void ginit(char **);
static void collect(register char *);
static void acollect(register char *);
static void sort(void);
static void expand(char *);
static void matchdir(char *);
static int execbrc(char *, char *);
static int match(char *, char *);
static int amatch(char *, char *);
static void Gcat(register char *, register char *);
static void rscan(register char **, int (*f) (register char));
static int tglob(register char c);
static int gethdir(char *);
int letter(register char);
int digit(register char);
int any(register int, register char *);
int blklen(register char **);
char **blkcpy(char **, register char **);
char *globerr;
char *home;
extern int errno;
static int globcnt;
char *globchars = "`{[*?";
static int globbed;
static char *entp;
static char **sortbas;
#ifdef OTHER_PASSWD
#include "getpwnam.h"
extern char _path_passwd[];
#endif
char **ftpglob(register char *v)
{
char *vv[2];
fatal("Out of memory");
}
}
fixpath(v);
if (v[0] == '\0')
v = "*";
vv[0] = v;
gflag = 0;
if (gflag == 0) {
}
*gpathp = 0;
globcnt = 0;
collect(v);
return (0);
}
else
}
{
agargv[0] = 0;
gargc = 0;
}
{
sort();
}
else
}
{
*gpathp = 0;
globbed = 0;
sort();
}
static int
{
}
static void sort(void)
{
if (!globerr)
}
{
register char *cs;
if (globerr)
return;
addpath('~');
*gpathp = 0;
globerr = "Unknown user name after ~";
/* memmove used as strings overlap */
}
else
}
}
if (*cs == 0) {
if (!globbed)
globcnt++;
}
goto endit;
}
}
if (*cs == '/')
*gpathp = 0;
if (*oldcs == '{') {
return;
}
*gpathp = 0;
}
{
#ifdef HAVE_DIRENT_H
#else
#endif
if (globbed)
return;
goto patherr2;
}
#ifdef HAVE_DIRFD
#else /* HAVE_DIRFD */
#endif /* HAVE_DIRFD */
goto patherr1;
goto patherr1;
}
continue;
globcnt++;
}
}
return;
globerr = "Bad directory components";
}
static int execbrc(char *p, char *s)
{
int brclev = 0;
if (lm >= restbufend)
return (0);
}
switch (*pe) {
case '{':
brclev++;
continue;
case '}':
if (brclev == 0)
goto pend;
brclev--;
continue;
case '[':
continue;
if (!*pe) {
globerr = "Missing ]";
return (0);
}
continue;
}
}
pend:
globerr = "Missing }";
return (0);
}
case '{':
brclev++;
continue;
case '}':
if (brclev) {
brclev--;
continue;
}
goto doit;
case ',' | QUOTE:
case ',':
if (brclev)
continue;
doit:
*pm = 0;
return (0);
if (s == 0) {
*gpathp = 0;
}
return (1);
sort();
continue;
case '[':
continue;
if (!*pm) {
globerr = "Missing ]";
return (0);
}
continue;
}
}
return (0);
}
static int match(char *s, char *p)
{
register int c;
register char *sentp;
if (*s == '.' && *p != '.')
return (0);
entp = s;
c = amatch(s, p);
return (c);
}
static int amatch(char *s, char *p)
{
register int scc;
char *sgpathp;
int c, cc;
globbed = 1;
for (;;) {
switch (c = *p++) {
case '{':
case '[':
ok = 0;
lc = 077777;
while ((cc = *p++)) {
if (cc == ']') {
if (ok)
break;
return (0);
}
if (cc == '-') {
ok++;
}
ok++;
}
if (cc == 0) {
globerr = "Missing ]";
return (0);
}
continue;
case '*':
if (!*p)
return (1);
if (*p == '/') {
p++;
goto slash;
} else if (*p == '*') {
s--;
continue;
}
s--;
do {
if (amatch(s, p))
return (1);
} while (*s++);
return (0);
case 0:
return (scc == 0);
default:
if (c != scc)
return (0);
continue;
case '?':
if (scc == 0)
return (0);
continue;
case '/':
if (scc)
return (0);
s = entp;
while (*s)
addpath(*s++);
addpath('/');
if (*p == 0) {
globcnt++;
}
else
expand(p);
*gpathp = 0;
return (0);
}
}
}
{
if (globerr)
return;
globerr = "Arguments too long";
return;
}
if (len > MAXPATHLEN) {
globerr = "Pathname too long";
return;
}
char **tmp;
(agargv_size + GAVSIZ) * sizeof (char *));
fatal("Out of memory");
} else {
agargv_size += GAVSIZ;
}
}
gargc++;
}
static void addpath(char c)
{
if (gpathp >= lastgpathp)
globerr = "Pathname too long";
else {
*gpathp++ = c;
*gpathp = 0;
}
}
static void rscan(register char **t, int (*f) (register char))
{
register char *p, c;
while ((p = *t++)) {
if (*p == '~')
gflag |= 2;
continue;
while ((c = *p++))
(*f) (c);
}
}
static int tglob(register char c)
{
return (c);
}
int letter(register char c)
{
return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
|| (c == '_'));
}
int digit(register char c)
{
return (c >= '0' && c <= '9');
}
int any(register int c, register char *s)
{
while (*s)
if (*s++ == c)
return (1);
return (0);
}
{
register int i = 0;
while (*av++)
i++;
return (i);
}
{
continue;
return (oav);
}
{
if (av) {
while (*av)
}
}
{
fatal("Out of memory");
return (ep);
}
char **copyblk(register char **v)
{
sizeof(char **)));
if (nv == (char **) 0)
fatal("Out of memory");
}
{
while (*cp)
cp++;
return (cp);
}
/*
* Extract a home directory from the password file
* The argument points to a buffer where the name of the
* user whose home directory is sought is currently.
* We write the home directory of the user back there.
*/
{
#ifdef OTHER_PASSWD
#else
#endif
return (1);
return (0);
}