/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "defs.h"
#include <string.h>
char *path;
char *pathp;
char *lastpathp;
char *tpathp;
int nleft;
char *entp;
char **sortbase;
char *index();
static void addpath(char c);
static void expsh(char *s);
static void expstr(char *s);
static int execbrc(char *p, char *s);
#define MIN(a, b) ((a) < (b) ? (a) : (b))
/*
* Take a list of names and expand any macros, etc.
* wh = E_VARS if expanding variables.
* wh = E_SHELL if expanding shell characters.
* wh = E_TILDE if expanding `~'.
* or any of these or'ed together.
*
*/
struct namelist *
int wh;
{
register int n;
if (debug) {
}
if (wh == 0) {
register char *cp;
return (list);
}
*pathp = '\0';
tilde = "";
eargc = 0;
*eargv = 0;
/*
* Walk the name list and expand names into eargv[];
*/
/*
* Take expanded list of names from eargv[] and build a new list.
*/
for (n = 0; n < eargc; n++) {
else {
}
}
if (debug) {
printf("expanded list = ");
}
return (list);
}
static void
expstr(s)
char *s;
{
char *tail;
extern char homedir[];
if (s == NULL || *s == '\0')
return;
*cp++ = '\0';
if (*cp == '\0') {
yyerror("no variable name after '$'");
return;
}
cp++;
yyerror("unmatched '{'");
return;
}
if (*cp == '\0') {
yyerror("no variable name after '$'");
return;
}
} else {
*tail = '\0';
}
if (savec != '\0')
}
return;
}
return;
}
Cat(s, "");
sort();
return;
}
if (*s == '~') {
cp = ++s;
tilde = "~";
} else {
*cp1++ = '~';
do {
yyerror("User name too long");
return;
}
*cp1 = '\0';
static char unknown_user[] =
": unknown user name";
sizeof (unknown_user));
return;
}
}
s = cp;
}
;
} else {
tilde = "";
}
*pathp = '\0';
else
sort();
return;
}
expany = 0;
expsh(s);
sort();
}
static int
{
}
/*
* If there are any Shell meta characters in the name,
* expand into a list, after searching directory
*/
static void
expsh(s)
char *s;
{
register char *cp;
cp = s;
if (*cp == '\0') {
else
}
goto endit;
}
}
if (*cp == '/')
*pathp = '\0';
if (*oldcp == '{') {
return;
}
*pathp = '\0';
}
static void
char *pattern;
{
if (expany)
return;
goto patherr2;
}
goto patherr1;
goto patherr1;
}
else {
lastpathp) {
goto patherr1;
}
*pathp = '\0';
}
}
return;
{
else
}
}
static int
execbrc(p, s)
char *p, *s;
{
int brclev = 0;
yyerror("Pathname too long");
return (0);
}
}
switch (*pe) {
case '{':
brclev++;
continue;
case '}':
if (brclev == 0)
goto pend;
brclev--;
continue;
case '[':
continue;
if (!*pe)
yyerror("Missing ']'");
continue;
}
pend:
yyerror("Missing '}'");
return (0);
}
case '{':
brclev++;
continue;
case '}':
if (brclev) {
brclev--;
continue;
}
goto doit;
case ',':
if (brclev)
continue;
doit:
*pm = 0;
yyerror("Pathname too long");
return (0);
}
if (s == 0) {
*pathp = 0;
return (1);
sort();
continue;
case '[':
continue;
if (!*pm)
yyerror("Missing ']'");
continue;
}
return (0);
}
int
match(s, p)
char *s, *p;
{
register int c;
register char *sentp;
if (*s == '.' && *p != '.')
return (0);
entp = s;
c = amatch(s, p);
return (c);
}
int
amatch(s, p)
register char *s, *p;
{
register int scc;
char *spathp;
int c, cc;
expany = 1;
for (;;) {
switch (c = *p++) {
case '{':
case '[':
ok = 0;
lc = 077777;
while (cc = *p++) {
if (cc == ']') {
if (ok)
break;
return (0);
}
if (cc == '-') {
ok++;
} else
ok++;
}
if (cc == 0) {
yyerror("Missing ']'");
return (0);
}
continue;
case '*':
if (!*p)
return (1);
if (*p == '/') {
p++;
goto slash;
}
for (s--; *s; s++)
if (amatch(s, p))
return (1);
return (0);
case '\0':
return (scc == '\0');
default:
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') {
else
} else
expsh(p);
*pathp = '\0';
return (0);
}
}
}
int
smatch(s, p)
register char *s, *p;
{
register int scc;
int c, cc;
for (;;) {
switch (c = *p++) {
case '[':
ok = 0;
lc = 077777;
while (cc = *p++) {
if (cc == ']') {
if (ok)
break;
return (0);
}
if (cc == '-') {
ok++;
} else
ok++;
}
if (cc == 0) {
yyerror("Missing ']'");
return (0);
}
continue;
case '*':
if (!*p)
return (1);
for (s--; *s; s++)
if (smatch(s, p))
return (1);
return (0);
case '\0':
return (scc == '\0');
default:
return (0);
continue;
case '?':
if (scc == 0)
return (0);
continue;
}
}
}
static void
{
register char *s;
fatal("Arguments too long\n");
if (s == NULL)
fatal("ran out of memory\n");
;
s--;
;
}
static void
addpath(char c)
{
yyerror("Pathname too long");
else {
*pathp = '\0';
}
}
/*
* Expand file names beginning with `~' into the
* user's home directory path name. Return a pointer in buf to the
* part corresponding to `file'.
*/
char *
char buf[];
unsigned int len;
register char *file;
{
extern char homedir[];
if (*file != '~') {
return (NULL);
}
return (buf);
}
if (*++file == '\0') {
} else if (*file == '/') {
} else {
s3++;
if (*s3 == '/')
*s3 = '\0';
else
*s3 = '/';
return (NULL);
}
}
*s3 = '/';
}
;
s2++;
;
}
return (NULL);
}
return (s2);
}