home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk458.lzh
/
Csh
/
src
/
sub.c
< prev
Wrap
C/C++ Source or Header
|
1991-02-15
|
13KB
|
617 lines
/*
* SUB.C
*
* (c)1986 Matthew Dillon 9 October 1986
*
* Version 2.07M by Steve Drew 10-Sep-87
*
* Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
*
*/
#define HM_STR 0 /* various HISTORY retrieval modes */
#define HM_REL 1
#define HM_ABS 2
seterr()
{
char buf[32];
int stat;
sprintf(buf, "%d", Lastresult);
set_var(LEVEL_SET, v_lasterr, buf);
stat = atoi(get_var(LEVEL_SET, v_stat));
if (stat < Lastresult) set_var(LEVEL_SET, v_stat, buf);
}
#define ISSPACE(c) ((c)==' ' || (c)==9 || (unsigned char)(c)==0xA0)
char *next_word(str)
register char *str;
{
while (*str && ! ISSPACE(*str)) ++str;
while (*str && ISSPACE(*str)) ++str;
return str;
}
hasspace(s)
register char *s;
{
for ( ; *s; s++)
if (ISSPACE(*s)) return 1;
return 0;
}
char *compile_av(av, start, end, delim, quote)
char **av;
unsigned char delim;
{
register char *cstr, *p;
int len;
register unsigned int i;
len = 1;
for (i = start; i < end; ++i) len += strlen(av[i]) + 3;
p = cstr = malloc(len);
*cstr = '\0';
for (i = start; i < end; ++i) {
if (debug) fprintf (stderr, "AV[%2d] :%s:\n", i, av[i]);
if (quote && hasspace(av[i]))
p += sprintf(p, "\"%s\"", av[i]);
else
p += sprintf(p, "%s", av[i]);
if (i+1 < end) *p++=delim;
}
*p='\0';
return cstr;
}
/*
* FREE(ptr) --frees without actually freeing, so the data is still good
* immediately after the free.
*/
Free(ptr)
char *ptr;
{
static char *old_ptr;
if (old_ptr) free (old_ptr);
old_ptr = ptr;
}
/*
* Add new string to history (H_head, H_tail, H_len,
* S_histlen
*/
add_history(str)
char *str;
{
register struct HIST *hist;
if (H_head != NULL && strcmp(H_head->line, str) == 0)
return(0);
while (H_len > S_histlen)
del_history();
hist = (struct HIST *)malloc (sizeof(struct HIST));
if (H_head == NULL) {
H_head = H_tail = hist;
hist->next = NULL;
} else {
hist->next = H_head;
H_head->prev = hist;
H_head = hist;
}
hist->prev = NULL;
hist->line = malloc (strlen(str) + 1);
strcpy (hist->line, str);
++H_len;
}
del_history()
{
if (H_tail) {
--H_len;
++H_tail_base;
free (H_tail->line);
if (H_tail->prev) {
H_tail = H_tail->prev;
free (H_tail->next);
H_tail->next = NULL;
} else {
free (H_tail);
H_tail = H_head = NULL;
}
}
}
char *
get_history(ptr)
char *ptr;
{
register struct HIST *hist;
register int len;
int mode = HM_REL;
int num = 1;
char *str;
char *result = NULL;
if (ptr[1] >= '0' && ptr[1] <= '9') {
mode = HM_ABS;
num = atoi(&ptr[1]);
goto skip;
}
switch (ptr[1]) {
case '!':
break;
case '-':
num += atoi(&ptr[2]);
break;
default:
mode = HM_STR;
str = ptr + 1;
break;
}
skip:
switch (mode) {
case HM_STR:
len = strlen(str);
for (hist = H_head; hist; hist = hist->next) {
if (strncmp(hist->line, str, len) == 0 && *hist->line != '!') {
result = hist->line;
break;
}
}
break;
case HM_REL:
for (hist = H_head; hist && num--; hist = hist->next);
if (hist)
result = hist->line;
break;
case HM_ABS:
len = H_tail_base;
for (hist = H_tail; hist && len != num; hist = hist->prev, ++len);
if (hist)
result = hist->line;
break;
}
if (result) {
fprintf(stderr,"%s\n",result);
return(result);
}
printf("History failed\n");
return ("");
}
replace_head(str)
char *str;
{
if (str == NULL)
str = "";
if (H_head) {
free (H_head->line);
H_head->line = malloc (strlen(str)+1);
strcpy (H_head->line, str);
}
}
pError(str)
char *str;
{
int ierr = (long)IoErr();
ierror(str, ierr);
}
ierror(str, err)
register char *str;
{
register struct PERROR *per = Perror;
if (err) {
for (; per->errstr; ++per) {
if (per->errnum == err) {
fprintf (stderr, "%s%s%s\n",
per->errstr,
(str) ? ": " : "",
(str) ? str : "");
return ((short)err);
}
}
fprintf (stderr, "Unknown DOS error %d %s\n", err, (str) ? str : "");
}
return ((short)err);
}
/*
* Disk directory routines
*
* dptr = dopen(name, stat)
* struct DPTR *dptr;
* char *name;
* int *stat;
*
* dnext(dptr, name, stat)
* struct DPTR *dptr;
* char **name;
* int *stat;
*
* dclose(dptr) -may be called with NULL without harm
*
* dopen() returns a struct DPTR, or NULL if the given file does not
* exist. stat will be set to 1 if the file is a directory. If the
* name is "", then the current directory is openned.
*
* dnext() returns 1 until there are no more entries. The **name and
* *stat are set. *stat = 1 if the file is a directory.
*
* dclose() closes a directory channel.
*
*/
struct DPTR *
dopen(name, stat)
char *name;
int *stat;
{
struct DPTR *dp;
*stat = 0;
dp = (struct DPTR *)malloc(sizeof(struct DPTR));
if (*name == '\0')
dp->lock = DupLock(Myprocess->pr_CurrentDir);
else
dp->lock = Lock (name,ACCESS_READ);
if (dp->lock == NULL) {
free (dp);
return NULL;
}
dp->fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
if (!Examine (dp->lock, dp->fib)) {
pError (name);
dclose (dp);
return NULL;
}
if (dp->fib->fib_DirEntryType >= 0) *stat = 1;
return dp;
}
dnext(dp, pname, stat)
struct DPTR *dp;
char **pname;
int *stat;
{
if (dp == NULL) return (0);
if (ExNext (dp->lock, dp->fib)) {
*stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
*pname = dp->fib->fib_FileName;
return (1);
}
return (0);
}
dclose(dp)
struct DPTR *dp;
{
if (dp == NULL)
return (1);
if (dp->fib)
FreeMem (dp->fib,(long)sizeof(*dp->fib));
if (dp->lock)
UnLock (dp->lock);
free (dp);
return (1);
}
isdir(file)
char *file;
{
register struct DPTR *dp;
int stat;
stat = 0;
if (dp = dopen (file, &stat))
dclose(dp);
return (stat == 1);
}
free_expand(av)
register char **av;
{
char **base = av;
if (av) {
while (*av) {
free (*av);
++av;
}
free (base);
}
}
/*
* EXPAND(base,pac)
* base - char * (example: "df0:*.c")
* pac - int * will be set to # of arguments.
*
* 22-May-87 SJD. Heavily modified to allow recursive wild carding and
* simple directory/file lookups. Returns a pointer to
* an array of pointers that contains the full file spec
* eg. 'df0:c/sear*' would result in : 'df0:C/Search'
*
* Now no longer necessary to Examine the files a second time
* in do_dir since expand will return the full file info
* appended to the file name. Set by formatfile().
* eg. fullfilename'\0'rwed NNNNNN NNNN DD-MMM-YY HH:MM:SS
*
* Caller must call free_expand when done with the array.
*
* base bname = ename =
* ------ ------- -------
* "*" "" "*"
* "!*.info" "" "*.info" (wild_exclude set)
* "su*d/*" "" "*" (tail set)
* "file.*" "" "file.*"
* "df0:c/*" "df0:c" "*"
* "" "" "*"
* "df0:.../*" "df0:" "*" (recur set)
* "df0:sub/.../*" "df0:sub" "*" (recur set)
*
* ---the above base would be provided by execom.c or do_dir().
* ---the below base would only be called from do_dir().
*
* "file.c" "file.c" "" if (dp == 0) fail else get file.c
* "df0:" "df0:" "*"
* "file/file" "file/file" "" (dp == 0) so fail
* "df0:.../" "df0:" "*" (recur set)
*
*/
char **
expand(base, pac)
char *base;
int *pac;
{
register char *ptr;
char **eav = (char **)malloc(sizeof(char *) * (2));
short eleft, eac;
char *name;
char *svfile();
char *bname, *ename, *tail;
int stat, recur, scr, bl;
register struct DPTR *dp;
*pac = recur = eleft = eac = 0;
base = strcpy(malloc(strlen(base)+1), base);
for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
if (!*ptr) /* no wild cards */
--ptr;
else
for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
if (ptr < base) {
bname = strcpy (malloc(1), "");
} else {
scr = ptr[1];
ptr[1] = '\0';
if (!strcmp(ptr-3,".../")) {
recur = 1;
*(ptr-3) = '\0';
}
bname = strcpy (malloc(strlen(base)+2), base);
ptr[1] = scr;
}
bl = strlen(bname);
ename = ++ptr;
for (; *ptr && *ptr != '/'; ++ptr);
scr = *ptr;
*ptr = '\0';
if (scr) ++ptr;
tail = ptr;
if ((dp = dopen (bname, &stat)) == NULL || (stat == 0 && *ename)) {
free (bname);
free (base);
free (eav);
return (NULL);
}
if (!stat) { /* eg. 'dir file' */
char *p,*s;
for(s = p = bname; *p; ++p) if (*p == '/' || *p == ':') s = p;
if (s != bname) ++s;
*s ='\0';
eav[eac++] = svfile(bname,dp->fib->fib_FileName,dp->fib);
goto done;
}
if (!*ename) ename = "*"; /* eg. dir df0: */
if (*bname && bname[bl-1] != ':' && bname[bl-1] != '/') { /* dir df0:c */
bname[bl] = '/';
bname[++bl] = '\0';
}
while ((dnext (dp, &name, &stat)) && !breakcheck()) {
int match = compare_ok(ename,name,0);
if (match && !(!recur && *tail)) {
if (eleft < 2) {
char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
movmem (eav, scrav, (eac + 1) << 2);
free (eav);
eav = scrav;
eleft = 10;
}
eav[eac++] = svfile(bname,name,dp->fib);
--eleft;
}
if ((*tail && match) || recur) {
int alt_ac;
char *search, **alt_av, **scrav;
BPTR lock;
if (!stat) /* expect more dirs, but this not a dir */
continue;
lock = CurrentDir (dp->lock);
search = malloc(strlen(ename)+strlen(name)+strlen(tail)+5);
strcpy (search, name);
strcat (search, "/");
if (recur) {
strcat(search, ".../");
strcat(search, ename);
}
strcat (search, tail);
scrav = alt_av = expand (search, &alt_ac);
/* free(search); */
CurrentDir (lock);
if (scrav) {
while (*scrav) {
int l;
if (eleft < 2) {
char **scrav = (char **)malloc(sizeof(char *) * (eac + 10));
movmem (eav, scrav, (eac + 1) << 2);
free (eav);
eav = scrav;
eleft = 10;
}
l = strlen(*scrav);
scrav[0][l] = ' ';
eav[eac] = malloc(bl+l+45);
strcpy(eav[eac], bname);
strcat(eav[eac], *scrav);
eav[eac][l+bl] = '\0';
free (*scrav);
++scrav;
--eleft, ++eac;
}
free (alt_av);
}
}
}
done:
dclose (dp);
*pac = eac;
eav[eac] = NULL;
free (bname);
free (base);
if (eac) {
return (eav);
}
free (eav);
return (NULL);
}
char *strupr(s)
register char *s;
{
while (*s) *s=toupper(*s), s++;
return s;
}
char *strlwr(s)
register char *s;
{
while (*s) *s=tolower(*s), s++;
return s;
}
/*
* Compare a wild card name with a normal name
*/
compare_ok(wild, name, casedep)
char *wild, *name;
{
int queryflag;
char buf[260], wildbuf[260], *lowname;
if (queryflag=(*wild=='&')) wild++;
if (*wild=='!') *wild='~';
if (! casedep) {
strupr(wild);
strcpy(buf,name);
strupr(buf);
lowname=buf;
}
else lowname=name;
PreParse(wild, wildbuf);
if ( ! PatternMatch(wildbuf,lowname)) return 0;
if (queryflag) {
printf("Select \23337m%-16s\2330m [y/n] ? ",name);
gets(buf);
return (toupper(*buf)=='Y');
}
return 1;
}
char *svfile(s1,s2,fib)
char *s1,*s2;
FIB *fib;
{
char *p = malloc (strlen(s1)+strlen(s2)+45);
strcpy(p, s1);
strcat(p, s2);
formatfile(p,fib);
return p;
}
/* will have either of these formats:
*
* fullfilename'\0'hsparwed <Dir> DD-MMM-YY HH:MM:SS\n'\0'
* fullfilename'\0'hsparwed NNNNNN NNNN DD-MMM-YY HH:MM:SS\n'\0'
* 1111111111222222222233333333334 4 4
* 01234567890123456789012345678901234567890 1 2
*/
formatfile(str,fib)
char *str;
FIB *fib;
{
char *dates();
int i;
while(*str++);
for (i=7; i>=0; i--)
*str++ = ((fib->fib_Protection & (1L<<i)) ? "hspa----" : "----rwed")[7-i];
if (fib->fib_DirEntryType < 0)
sprintf(str," %6ld %4ld ", (long)fib->fib_Size, (long)fib->fib_NumBlocks);
else strcpy(str," <Dir> ");
strcat(str,dates(&fib->fib_Date));
}
/* Sort routines */
long cmp(s1, s2)
char **s1, **s2;
{
return (long)Strcmp(*s1, *s2);
}
Cmp() {
#asm
public _geta4
movem.l d2-d3/a4/a6,-(sp)
movem.l a0/a1,-(sp)
bsr _geta4
bsr _cmp
addq.l #8,sp
movem.l (sp)+,d2-d3/a4/a6
#endasm
}
QuickSort(av, n)
char *av[];
int n;
{
QSort(av, (long)n, 4L, Cmp);
}