This is glob.c in view mode; [Download] [Up]
#include <ctype.h>
#include <dir.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <io.h>
#ifdef __GO32__
#include <sys/farptr.h>
#else
#include <alloc.h>
#endif
#define extern
#include "glob.h"
#undef extern
int (*__glob_sense_expand_from_proxy)(int original_expand_wildcards) = 0;
static int expand_wildcards = 0;
static void parse_chars(void *ptr, int (*func)(void *ptr));
static int argv_max = 0;
static int
string_getc(void *ptr)
{
int c = *(*(char **)ptr)++;
return c;
}
static int
file_getc(void *ptr)
{
return fgetc((FILE *)ptr);
}
static char *
get_proxy(int i)
{
int len;
char *rv;
int seg = __glob_proxy_vals[1];
int ofs = __glob_proxy_vals[2];
int c;
#ifdef __GO32__
_farsetsel(_go32_conventional_mem_selector());
ofs = seg * 16 + _farnspeekw(seg*16+ofs+2*i);
for (len=0; _farnspeekb(ofs+len); len++);
rv = (char *)malloc(len+1);
if (!rv)
{
fprintf(stderr, "Error: out of memory gathering arguments\n");
exit(1);
}
for (len=0; (c = _farnspeekb(ofs+len)) != 0; len++)
rv[len] = c;
rv[len] = 0;
#else
ofs = peek(seg, ofs+2*i);
for (len=0; peekb(seg, ofs+len); len++);
rv = (char *)malloc(len+1);
if (!rv)
{
fprintf(stderr, "Error: out of memory gathering arguments\n");
exit(1);
}
for (len=0; (c = peekb(seg, ofs+len)) != 0; len++)
rv[len] = c;
rv[len] = 0;
#endif
return rv;
}
static void
stash_arg_at(char *arg, int slot, int dup)
{
if (__glob_argv == 0)
argv_max = 0;
if (slot >= argv_max)
{
int newmax = (argv_max + 1)*2;
if (__glob_argv)
__glob_argv = (char **)realloc(__glob_argv, newmax * sizeof(char *));
else
{
__glob_argv = (char **)malloc(newmax * sizeof(char *));
__glob_argc = 0;
argv_max = 0;
}
if (!__glob_argv)
{
fprintf(stderr, "Error: out of memory gathering arguments\n");
exit(1);
}
while (argv_max < newmax)
__glob_argv[argv_max++] = 0;
}
__glob_argv[slot] = arg ? (dup ? strdup(arg) : arg) : 0;
if (arg && !__glob_argv[slot])
{
fprintf(stderr, "Error: out of memory gathering arguments\n");
exit(1);
}
if (arg && (slot >= __glob_argc))
__glob_argc = slot + 1;
}
static void
stash_arg(char *arg)
{
stash_arg_at(arg, __glob_argc ? __glob_argc : 1, 1);
}
static void
free_args(void)
{
int i;
for (i=0; i<argv_max; i++)
if (__glob_argv[i])
{
free(__glob_argv[i]);
__glob_argv[i] = 0;
}
__glob_argc = 0;
}
#define SINGLE_QUOTE '\''
#define DOUBLE_QUOTE '"'
#define EOS '\0'
#define isslash(c) ((c) == '\\' || (c) == '/')
static char *
rangematch(char *pattern, char test)
{
char c, c2;
int negate, ok;
if ((negate = (*pattern == '!')) != 0)
++pattern;
/*
* TO DO: quoting
*/
for (ok = 0; (c = *pattern++) != ']';)
{
if (c == EOS)
return(NULL); /* illegal pattern */
if (*pattern == '-' && (c2 = pattern[1]) != EOS && c2 != ']')
{
if (c <= test && test <= c2)
ok = 1;
else if (isalpha(test) && c <= (test^0x20) && (test^0x20) <= c2)
ok = 1;
pattern += 2;
}
else if (tolower(c) == tolower(test))
ok = 1;
}
return(ok == negate ? NULL : pattern);
}
static int hasdot;
static int
fnmatch(char *pattern,
char *string)
{
register char c;
char test, *rangematch();
for (;;)
switch (c = *pattern++)
{
case EOS:
return(*string == EOS);
case '?':
if ((test = *string++) == EOS ||
isslash(test))
return(0);
break;
case '*':
c = *pattern;
/* collapse multiple stars */
while (c == '*')
c = *++pattern;
/* optimize for pattern with * at end or before / */
if (c == EOS || (c == '.' && pattern[1] == EOS && !hasdot))
return(!strchr(string, '/'));
else if (isslash(c))
{
if ((string = strpbrk(string, "/\\")) == NULL)
return(0);
break;
}
/* general case, use recursion */
while ((test = *string) != EOS)
{
if (fnmatch(pattern, string))
return(1);
if (isslash(test))
break;
++string;
}
return(0);
case '[':
if ((test = *string++) == EOS ||
isslash(test))
return(0);
if ((pattern = rangematch(pattern, test)) == NULL)
return(0);
break;
default:
string++;
if (tolower(c) != tolower(string[-1]))
return(0);
break;
}
}
#define PATH_MAX 140
static int lowcase = 0;
static int mustexist = 0;
static void
wildcard1(char *buf, char *bp, char *fp)
{
char *slpos = strpbrk(fp, "/\\"), slsave='-';
int done, i;
struct ffblk ff;
char *wildchars;
if (slpos)
{
slsave = *slpos;
*slpos = 0;
}
for (i=0; fp[i]; i++)
{
if (islower(fp[i]))
lowcase = 1;
if (isupper(fp[i]))
lowcase = 0;
}
wildchars = strpbrk(fp, "*?[]");
if (!expand_wildcards || wildchars==0)
{
strcpy(bp, fp);
if (slpos)
{
int bpl = strlen(bp);
bp[bpl++] = slsave;
bp[bpl] = 0;
wildcard1(buf, bp+bpl, slpos+1);
}
else
{
if (wildchars == 0 && mustexist)
{
if (access(buf, 0) == 0)
stash_arg(buf);
}
else
stash_arg(buf);
}
}
else
{
strcpy(bp, "*.*");
done = findfirst(buf, &ff, FA_RDONLY|FA_DIREC|FA_ARCH);
while (!done)
{
if (ff.ff_name[0] != '.' || fp[0] == '.')
{
if (lowcase)
strlwr(ff.ff_name);
hasdot = strchr(ff.ff_name, '.')!=0;
if (fnmatch(fp, ff.ff_name))
{
strcpy(bp, ff.ff_name);
if (slpos)
{
int bpl = strlen(bp);
bp[bpl++] = slsave;
bp[bpl] = 0;
mustexist++;
wildcard1(buf, bp+bpl, slpos+1);
mustexist--;
}
else
stash_arg(buf);
}
}
done = findnext(&ff);
}
}
if (slpos)
*slpos = slsave;
}
static int
argv_cmp(void *av, void *bv)
{
register char *a = *(char **)av;
register char *b = *(char **)bv;
return strcmp(a, b);
}
static void
wildcard(char *arg)
{
char buf[140];
char *bp, *fp;
int oarg;
lowcase = 1;
bp=buf;
fp=arg;
if (fp[1] == ':')
{
*bp++ = *fp++;
*bp++ = *fp++;
}
if (*fp == '/' || *fp == '\\')
*bp++ = *fp++;
oarg = __glob_argc;
if (oarg < 1) oarg = 1;
wildcard1(buf, bp, fp);
if (oarg >= __glob_argc)
stash_arg(arg);
else
qsort(__glob_argv+oarg, __glob_argc - oarg,
sizeof(char *), argv_cmp);
}
static void
expand_arg(char *arg)
{
if (arg[0] == '@')
{
FILE *f = fopen(arg+1, "r");
if (f)
{
parse_chars(f, file_getc);
fclose(f);
return;
}
}
else if (expand_wildcards && strspn("*?[]", arg))
wildcard(arg);
else
stash_arg(arg);
}
static void
parse_chars(void *ptr, int (*func)(void *ptr))
{
int quote = 0;
int needs_expansion = 0;
char argbuf[1000];
char *start = argbuf;
int pending_arg = 0;
int done = 0;
int unc = -2;
while (!done)
{
int c = (unc==-2) ? func(ptr) : unc;
unc = -2;
if (c <= 0)
{
if (pending_arg)
{
*start = 0;
if (needs_expansion)
expand_arg(argbuf);
else
stash_arg(argbuf);
pending_arg = 0;
start = argbuf;
}
done = 1;
}
else if (quote == SINGLE_QUOTE)
{
if (c == SINGLE_QUOTE)
quote = 0;
else
*start++ = c;
}
else if (quote == DOUBLE_QUOTE)
{
if (c == DOUBLE_QUOTE)
quote = 0;
else if (c == '\\')
{
unc = func(ptr);
if (strchr("\\'\"", unc))
{
*start++ = unc;
unc = -2;
}
else if (unc != '\n')
{
*start++ = c;
}
}
else
*start++ = c;
}
else if (isspace(c))
{
if (pending_arg)
{
*start = 0;
if (needs_expansion)
expand_arg(argbuf);
else
stash_arg(argbuf);
pending_arg = 0;
start = argbuf;
}
}
else
{
if (c == SINGLE_QUOTE || c == DOUBLE_QUOTE)
quote = c;
else if (c == '\\')
{
unc = func(ptr);
if (unc == '\n')
unc = -2;
else if (strchr("\\'\"", unc) || isspace(unc))
{
*start++ = unc;
unc = -2;
}
else
*start++ = '\\';
}
else
{
if (strchr("*?[]", c) || (c == '@' && start == argbuf))
needs_expansion = 1;
*start++ = c;
}
pending_arg = 1;
}
}
}
static int
getenvargs(void)
{
int i, ac;
char aname[10];
char *a0 = getenv("_argc");
if (!a0)
return 1;
ac = atoi(a0);
for (i=0; i<ac; i++)
{
sprintf(aname, "_argv%d", i);
if (i == 0)
stash_arg_at(getenv(aname), 0, 1);
else
expand_arg(getenv(aname));
}
return 0;
}
void
__glob_args(char *cmdline, char *dos_argv0, int _expand_wildcards)
{
expand_wildcards = _expand_wildcards;
free_args();
__glob_argc = 0;
__glob_proxy_count = 0;
if (getenvargs())
{
parse_chars(&cmdline, string_getc);
if (__glob_argc > 4 && strcmp(__glob_argv[1], "!proxy") == 0)
{
int i;
for (i=0; i+2 < __glob_argc; i++)
{
unsigned long pval = strtoul(__glob_argv[i+2], 0, 16);
__glob_proxy_vals[i] = (unsigned) pval;
}
free_args();
__glob_proxy_count = i;
if (__glob_sense_expand_from_proxy)
expand_wildcards = __glob_sense_expand_from_proxy(expand_wildcards);
stash_arg_at(get_proxy(0), 0, 1);
for (i=1; i<__glob_proxy_vals[0]; i++)
expand_arg(get_proxy(i));
}
else
stash_arg_at(dos_argv0, 0, 1);
}
stash_arg_at(0, __glob_argc, 0);
}
void
__glob_env(char *app_name)
{
FILE *djgpp_env;
char *djgpp_var = getenv("DJGPP");
char *copy;
if (djgpp_var)
{
djgpp_env = fopen(djgpp_var, "rt");
if (djgpp_env)
{
char line[2000];
char base[12], *bp, *a0p, *tb = (char *)line;
int this_prog = 1;
base[0] = '[';
bp = app_name;
for (a0p = bp; *a0p; a0p++)
if (strchr("\\/:", *a0p))
bp = a0p+1;
for (a0p=base+1; *bp && *bp != '.';)
*a0p++ = tolower(*bp++);
*a0p++ = ']';
*a0p++ = 0;
while (fgets(tb, 2000, djgpp_env))
{
tb[strlen(tb)-1] = 0;
if (tb[0] == 0)
continue;
if (tb[0] == '[')
{
if (strcmp(tb, base) == 0)
this_prog = 1;
else
this_prog = 0;
}
else
{
if (this_prog)
{
char *tb2 = tb+strlen(tb)+1;
char *sp=tb, *dp=tb2;
while (*sp != '=')
*dp++ = *sp++;
if (*tb2 == '+') /* non-overriding */
{
*dp = 0;
tb2++;
if (getenv(tb2))
continue; /* while fread */
}
*dp++ = *sp++; /* copy the '=' */
while (*sp)
{
if (*sp == '%')
{
char *pp;
if (sp[1] == '%')
{
*dp++ = '%';
sp += 2;
}
else
{
char ps, *e, *dirend;
int dirpart=0, apsemi=0;
int mapup=0, maplow=0, mapfs=0, mapbs=0;
while (strchr(":;/\\<>", sp[1]))
{
switch (sp[1])
{
case ':': dirpart=1; break;
case ';': apsemi=1; break;
case '/': mapfs=1; break;
case '\\': mapbs=1; break;
case '<': mapup=1; break;
case '>': maplow=1; break;
}
sp++;
}
for (pp=sp+1; *pp && *pp != '%'; pp++);
ps = *pp;
*pp = 0;
e = getenv(sp+1);
dirend = dp;
if (e)
{
while (*e)
{
char ec = *e++;
if (strchr("\\/:", ec))
dirend=dp;
if (mapup) ec = toupper(ec);
if (maplow) ec = tolower(ec);
if (mapfs && ec == '\\') ec = '/';
if (mapbs && ec == '/') ec = '\\';
*dp++ = ec;
}
}
if (dirpart)
dp = dirend;
if (apsemi && e)
*dp++ = ';';
if (ps == 0)
break;
sp = pp+1;
}
}
else
*dp++ = *sp++;
}
*dp++ = 0;
copy = strdup(tb2);
if (!copy)
{
fprintf(stderr, "Error: out of memory gathering environment\n");
exit(1);
}
putenv(copy);
}
}
}
fclose(djgpp_env);
}
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.