home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * 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
- * Version 5.00L by Urban Mueller 17-Feb-91
- *
- */
-
- #include "shell.h"
- #include "proto.h"
-
- static void del_history( void );
- static int dnext( struct DPTR *dp, char **pname, int *stat);
- static char *svfile( char *s1, char *s2, FIB *fib);
- static int exall( BPTR lock, char *path );
- static void quicksort( char **av, int n );
-
-
- #define HM_STR 0 /* various HISTORY retrieval modes */
- #define HM_REL 1
- #define HM_ABS 2
-
- void
- seterr( int err )
- {
- static int LastErr;
- char buf[32], *val;
- int stat=0;
-
- Lastresult=err;
-
- if( LastErr!=err ) {
- LastErr=err;
- sprintf(buf, "%d", err);
- set_var(LEVEL_SET, v_lasterr, buf);
-
- if( val=get_var(LEVEL_SET, v_stat))
- stat = atoi(val);
- if (stat < Lastresult) set_var(LEVEL_SET, v_stat, buf);
- }
- }
-
- char *
- next_word( char *str )
- {
- while (*str && ! ISSPACE(*str)) ++str;
- while (*str && ISSPACE(*str)) ++str;
- return str;
- }
-
- /*
- * FREE(ptr) --frees without actually freeing, so the data is still good
- * immediately after the free.
- */
-
-
- void
- Free( void *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
- */
-
- void
- add_history( char *str )
- {
- struct HIST *hist;
- char *get;
-
- for( get=str; *get; get++ )
- if( (*get&127)<' ')
- *get=' ';
-
- if (H_head != NULL && !strcmp(H_head->line, str))
- return;
- while (H_len > S_histlen)
- del_history();
- hist = (struct HIST *)salloc (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 = salloc (strlen(str) + 1);
- strcpy (hist->line, str);
- ++H_len;
- }
-
- static void
- 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( char *ptr, int echo, int occur )
- {
- struct HIST *hist;
- int len;
- int mode = HM_REL;
- int num = 1, found=0;
- char *str=NULL;
- 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;
- if( !occur || ++found==occur )
- 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( echo==1 )
- fprintf(stderr, result ? "%s\n" : "History failed\n", result);
- if( !result )
- if( echo==2 )
- DisplayBeep(NULL);
- else
- result="";
- return result;
- }
-
- void
- replace_head( char *str )
- {
- if (str && strlen(str) && H_head) {
- free (H_head->line);
- H_head->line = salloc (strlen(str)+1);
- strcpy (H_head->line, str);
- }
- }
-
-
- #if 0
- #define CDLEN 20
- static int cd_len=CDLEN, cd_read, cd_write, cd_current;
- static char *cd_hist[CDLEN];
-
- add_cdhist( char *str )
- {
- if( !str )
- return;
- if( cd_hist[cd_write] )
- free(cd_hist[cd_write]);
- cd_hist[cd_write++]=str;
- cd_write%=cd_len;
- cd_current=cd_write;
- }
-
- char *
- back_cdhist( void )
- {
- if( cd_current!=cd_write ) cd_current= --cd_current % cd_len;
- return cd_hist[cd_current];
- }
-
- char *
- forw_cdhist( void )
- {
- if( cd_current!=cd_read ) cd_current= ++cd_current % cd_len;
- return cd_hist[cd_current];
- }
- #endif
-
- void
- pError(char *str )
- {
- int ierr = (long)IoErr();
- ierror(str, ierr);
- }
-
- ierror( char *str, int err )
- {
- struct PERROR *per = Perror;
-
- setioerror(err);
-
- if (err) {
- for (; per->errstr; ++per) {
- if (per->errnum == err) {
- fprintf (stderr, "%s%s%s\n",
- per->errstr,
- (str) ? ": " : "",
- (str) ? str : "");
- return err;
- }
- }
- fprintf (stderr, "Unknown DOS error %d: %s\n", err, (str) ? str : "");
- }
- return err;
- }
-
- void
- setioerror( int err )
- {
- static int LastIoError=-1;
- char buf[20];
-
- IoError=err;
- if( IoError<0 ) IoError=0;
- if( LastIoError!=IoError) {
- LastIoError=IoError;
- sprintf(buf, "%d", IoError);
- set_var(LEVEL_SET, v_ioerr, buf);
- }
- }
-
- char *
- ioerror(int num)
- {
- struct PERROR *per = Perror;
-
- for ( ; per->errstr; ++per)
- if (per->errnum == num)
- return per->errstr;
- return NULL;
- }
-
- /*
- * 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 != 0 if the file is a directory.
- *
- * dclose() closes a directory channel.
- *
- */
-
- struct DPTR *
- dopen( char *name, int *stat)
- {
- struct DPTR *dp;
-
- IoError=0;
- *stat = 0;
- dp = (struct DPTR *)salloc(sizeof(struct DPTR));
- if (*name == '\0')
- dp->lock = DupLock(Myprocess->pr_CurrentDir);
- else
- dp->lock = Lock (name,ACCESS_READ);
- if (dp->lock == NULL) {
- IoError=IoErr();
- free (dp);
- return NULL;
- }
- dp->fib = (FIB *)SAllocMem((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;
- }
-
- static int
- dnext( struct DPTR *dp, char **pname, int *stat)
- {
- if (dp == NULL) return (0);
-
- if (ExNext (dp->lock, dp->fib)) {
- *stat = 0;
- if( dp->fib->fib_DirEntryType >= 0)
- *stat= dp->fib->fib_DirEntryType!=ST_USERDIR ? 2 : 1;
- *pname = dp->fib->fib_FileName;
- return 1;
- }
- return 0;
- }
-
- int
- dclose( 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;
- }
-
-
- int
- isdir( char *file )
- {
- struct DPTR *dp;
- int stat;
-
- stat = 0;
- if (dp = dopen (file, &stat))
- dclose(dp);
- return (stat!=0);
- }
-
-
- void
- free_expand( char **av )
- {
- char **get = av;
-
- if (av) {
- while (*get)
- free (*get++-sizeof(struct file_info));
- free (av);
- }
- }
-
- /*
- * 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( char *base, int *pac )
- {
- char *ptr;
- char **eav = (char **)salloc(sizeof(char *) * (2));
- short eleft, eac;
- char *name;
- char *bname, *ename, *tail;
- int stat, recur, scr, bl;
- struct DPTR *dp;
-
- IoError = *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 (salloc(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 **)salloc(sizeof(char *) * (eac + 10));
- memmove (scrav, eav, (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!=1) /* expect more dirs, but this not a dir */
- continue;
- lock = CurrentDir (dp->lock);
- search = salloc(strlen(ename)+strlen(name)+strlen(tail)+6);
- 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 **)salloc(sizeof(char *)*(eac+10));
- memmove ( scrav, eav, (eac + 1) << 2);
- free (eav);
- eav = scrav;
- eleft = 10;
- }
-
- l = strlen(*scrav);
- eav[eac] = salloc(bl+l+1+sizeof(struct file_info));
- memcpy( eav[eac], *scrav-sizeof(struct file_info),
- sizeof(struct file_info));
- eav[eac]+=sizeof(struct file_info);
- strcpy( eav[eac], bname);
- strcat( eav[eac], *scrav);
-
- free (*scrav-sizeof(struct file_info));
- ++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( char *s )
- {
- char *old=s;
- while (*s) *s=toupper(*s), s++;
- return old;
- }
-
- char *
- strlwr( char *s )
- {
- char *old=s;
- while (*s) *s=tolower(*s), s++;
- return old;
- }
-
- /*
- * Compare a wild card name with a normal name
- */
-
- int
- compare_ok( char *wild, char *name, int casedep)
- {
- 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 %s%-16s%s [y/n] ? ",o_hilite,name,o_lolite);
- gets(buf);
- return (toupper(*buf)=='Y');
- }
- return 1;
- }
-
- static char *
- svfile( char *s1, char *s2, FIB *fib)
- {
- int len=strlen(s1)+strlen(s2)+1;
- char *p = salloc (len+sizeof(struct file_info));
- struct file_info *info;
-
- info=(struct file_info *)p;
- p+=sizeof(struct file_info);
- strcpy(p, s1);
- strcat(p, s2);
- info->flags = fib->fib_Protection;
- if( fib->fib_DirEntryType<0 ) {
- info->size = fib->fib_Size;
- info->blocks= fib->fib_NumBlocks;
- } else {
- info->size = -1;
- info->blocks= 0;
- }
- if( fib->fib_Comment[0] )
- info->flags|= 1<<30;
- info->date=fib->fib_Date;
- info->class[0]=1;
- return p;
- }
-
-
-
- static FILE *out;
- static int NumDirs;
-
- void
- expand_all( char *name, FILE *file )
- {
- BPTR lock;
- char path[300];
- FIB *fib;
-
- out=file;
- printf( " %s\n", name );
- NumDirs=0;
-
- if(fib=AllocMem(sizeof(struct FileInfoBlock),0)) {
- if( lock=Lock( name, ACCESS_READ )) {
- strcpy( path, name );
- exall( lock, path );
- printf( "\n", NumDirs );
- }
- FreeMem(fib,sizeof(struct FileInfoBlock));
- }
- }
-
- static int
- exall( BPTR lock, char *path )
- {
- BPTR old, sublock;
- int len;
- struct FileInfoBlock *fib;
-
- old=CurrentDir( lock );
-
- if( !(fib=AllocMem(sizeof(struct FileInfoBlock),0)) )
- return 1;
-
- len=strlen( path );
- Examine( lock, fib );
- while( ExNext( lock, fib ) ) {
- if( fib->fib_DirEntryType==ST_USERDIR )
- if( sublock=Lock( fib->fib_FileName, ACCESS_READ )) {
- if( !len || path[len-1]==':' )
- sprintf(path+len,"%s", fib->fib_FileName);
- else
- sprintf(path+len,"/%s", fib->fib_FileName);
- fprintf( out, "%s\n", path );
- fprintf( stdout, " Directories: %d\015", ++NumDirs );
- fflush ( stdout );
- if(exall( sublock, path ))
- break;
- path[len]=0;
- }
- }
- FreeMem( fib, sizeof(struct FileInfoBlock));
- CurrentDir( old );
- return dobreak();
- }
-
-
-
- /* Sort routines */
-
- static int reverse, factor;
-
- int
- cmp( FILEINFO *s1, FILEINFO *s2)
- {
- return Strcmp( (char *)(s1+1), (char *)(s2+1) );
- }
-
- int
- sizecmp( FILEINFO *s1, FILEINFO *s2)
- {
- return s2->size - s1->size;
- }
-
- int
- datecmp( FILEINFO *s1, FILEINFO *s2 )
- {
- int r;
- struct DateStamp *d1=&s1->date, *d2=&s2->date;
- if( !(r= d2->ds_Days - d1->ds_Days))
- if( !(r=d2->ds_Minute - d1->ds_Minute ) )
- r=d2->ds_Tick - d1->ds_Tick;
- return r;
- }
-
-
- int
- numcmp( FILEINFO *s1, FILEINFO *s2 )
- {
- return atoi((char *)(s1+1))-atoi((char *)(s2+1));
- }
-
- static void
- enterclass( FILEINFO *info )
- {
- char *class, *iclass=info->class, *t;
-
- if( *iclass==1 ) {
- if( class=getclass( (char *)(info+1))) {
- strncpy( iclass, class, 11 );
- iclass[11]=0;
- if( t=index(iclass,0xA0))
- *t=0;
- } else
- iclass[0]=0;
- }
- }
-
- int
- classcmp( FILEINFO *info1, FILEINFO *info2 )
- {
- int r;
-
- enterclass( info1 );
- enterclass( info2 );
-
- r= Strcmp( info1->class, info2->class );
- if( !r ) r=Strcmp((char *)(info1+1),(char *)(info2+1));
- return r;
- }
-
-
- void
- QuickSort( char *av[], int n)
- {
- reverse=factor=0;
- DirQuickSort( av, n, cmp, 0, 0 );
- }
-
- static int (*compare)(FILEINFO *, FILEINFO *);
-
- static int
- docompare(char *s1,char *s2)
- {
- FILEINFO *i1=(FILEINFO *)s1-1, *i2=(FILEINFO *)s2-1;
- int r=(*compare)( i1,i2 );
-
- if( reverse ) r =-r;
- if( factor ) r+= factor*((i2->size<0) - (i1->size<0));
- return r;
- }
-
- #define QSORT
-
- void
- DirQuickSort( char *av[], int n, int (*func)(FILEINFO *,FILEINFO *), int rev, int fac)
- {
- reverse=rev; compare=func; factor=fac;
-
- quicksort( av, n-1 );
- }
-
- static void
- quicksort( char **av, int n )
- {
- char **i, **j, *x, *t;
-
-
- if( n>0 ) {
- i=av; j=av+n; x=av[ n>>1 ];
- do {
- while( docompare(*i,x)<0 ) i++;
- while( docompare(x,*j)<0 ) --j;
- if( i<=j )
- { t=*i; *i=*j; *j=t; i++; j--; }
- } while( i<=j );
-
- if( j-av < av+n-i ) {
- quicksort( av, j-av );
- quicksort( i , av+n-i);
- } else {
- quicksort( i , av+n-i);
- quicksort( av, j-av );
- }
- }
- }
-
- int
- filesize( char *name )
- {
- BPTR lock;
- struct FileInfoBlock *fib;
- int len=0;
-
- if( lock = Lock (name,ACCESS_READ)) {
- if( fib=(struct FileInfoBlock *)AllocMem(sizeof(*fib),MEMF_PUBLIC)) {
- if (Examine (lock, fib))
- len=fib->fib_Size;
- FreeMem( fib, sizeof(*fib));
- }
- UnLock(lock);
- }
- return len;
- }
-
-
- #ifndef MIN
- #define MIN(x,y) ((x)<(y)?(x):(y))
- #endif
-
- char **
- and( char **av1, int ac1, char **av2, int ac2, int *ac, int base )
- {
- char **av=(char **)salloc(MIN(ac1,ac2)*sizeof(char *) ), *str;
- int i, j, k=0;
-
- for( i=0; i<ac1; i++ )
- for( j=0, str=base ? BaseName(av1[i]) : av1[i]; j<ac2; j++ )
- if( !Strcmp(str, base ? BaseName(av2[j]) : av2[j]))
- av[k++]=av1[i];
- *ac=k;
- return av;
- }
-
- char **
- without( char **av1, int ac1, char **av2, int ac2, int *ac, int base )
- {
- char **av=(char **)salloc(ac1*sizeof(char *) ), *str;
- int i, j, k=0;
-
- for( i=0; i<ac1; i++ ) {
- for( j=0, str=base ? BaseName(av1[i]) : av1[i]; j<ac2; j++ )
- if( !Strcmp(str, base ? BaseName(av2[j]) : av2[j] ) )
- break;
- if( j==ac2 )
- av[k++]=av1[i];
- }
- *ac=k;
- return av;
- }
-
- char **
- or( char **av1, int ac1, char **av2, int ac2, int *ac, int base )
- {
- char **av=(char **)salloc((ac1+ac2)*sizeof(char *) ), *str;
- int i, j, k=0;
-
- for( i=0; i<ac1; i++ )
- av[k++]=av1[i];
-
- for( i=0; i<ac2; i++ ) {
- for( j=0, str=base ? BaseName(av2[i]) : av2[i]; j<ac1; j++ )
- if( !Strcmp(str, base ? BaseName(av1[j]) : av1[j] ) )
- break;
- if( j==ac1 )
- av[k++]=av2[i];
- }
-
- *ac=k;
- return av;
- }
-
- void
- clear_archive_bit( char *name )
- {
- struct DPTR *dp;
- int stat;
-
- if(dp = dopen(name,&stat) ) {
- SetProtection( name, dp->fib->fib_Protection&~FIBF_ARCHIVE);
- dclose( dp );
- }
- }
-
- char *
- itoa( int i )
- {
- static char buf[20];
- char *pos=buf+19;
- int count=4, flag=0;
-
- if( i<0 )
- flag=1, i=-i;
-
- do {
- if( !--count )
- count=3, *--pos=',';
- *--pos= i%10+'0';
- } while( i/=10 );
-
- if( flag )
- *--pos='-';
-
- return pos;
- }
-
- char *
- itok( int i )
- {
- static char buf[16], which;
- char *exp=" KMG", *ptr= buf+(which=8-which);
-
- do
- i=(i+512)/1024, exp++;
- while( i>1024 );
- sprintf( ptr,"%d%c",i,*exp);
-
- return ptr;
- }
-
- char *
- next_a0( char *str )
- {
- while( *str && (UBYTE)*str!=0xA0 && *str!='=' && *str!=',') str++;
- if( *str )
- return str+1;
- return NULL;
- }
-
- static int
- gethex( char *str, int l )
- {
- int i, val=0, n, c;
-
- if( *str=='.' ) return l==2 ? 256 : 0;
-
- for( i=0; i<l || !l; i++ ) {
- c=*str++;
- if ( c>='0' && c<='9' ) n=c-'0';
- else if( c>='a' && c<='f' ) n=c-'a'+10;
- else if( c>='A' && c<='F' ) n=c-'A'+10;
- else break;;
- val=16*val+n;
- }
- return (l && i!=l) ? -1 : val;
- }
-
- strwrdcmp( char *str, char *wrd )
- {
- int ret;
- char *ind=index(wrd,0xA0);
-
- if( ind ) *ind=0;
- ret=compare_ok(wrd,str,0);
- if( ind ) *ind=0xA0;
- return !ret;
- }
-
- int
- wrdlen( char *str )
- {
- char *old=str;
-
- while( *str && (UBYTE)*str!=0xA0 ) str++;
- return str-old;
- }
-
- char *
- getclass(char *file)
- {
- CLASS *cl;
- char *class, *str, *arg, *get, *buf;
- int offs, byte, len, fail;
- BPTR fh;
-
- if( isdir(file) ) return "dir";
-
- if( !(buf=calloc(1024,1))) return NULL;
- if( !(fh=Open(file,MODE_OLDFILE))) return NULL;
- len=Read( fh,buf,1023);
- Close(fh);
-
- for( cl=CRoot; cl; cl=cl->next ) {
- class=cl->name;
- if(!(str=next_a0(cl->name))) continue;
- while( str ) {
- if(!(arg=next_a0( str ))) goto nextclass;
- switch( *str ) {
- case 's':
- if( (offs=strlen(file)-wrdlen(arg))<0 ) break;
- if( !strwrdcmp(file+offs,arg)) goto found;
- break;
- case 'n':
- if( !strwrdcmp(BaseName(file),arg) ) goto found;
- break;
- case 'd':
- goto found;
- case 'o':
- offs=gethex(arg,0);
- if( !(arg=index(arg,','))) goto nextclass;
- if( offs>len-10 ) break;
- for( get=buf+offs, ++arg; (byte=gethex(arg,2))>=0; arg+=2 )
- if( (UBYTE)*get++!=byte && byte!=256 )
- goto nexttry;
- goto found;
- case 'c':
- if( !len )
- goto nexttry;
- for( get=buf, fail=0; get<buf+len; get++ )
- if( *get<9 || *get>13 && *get<32 || *get>127 )
- fail++;
- if( fail*8>len )
- goto nexttry;
- goto found;
- case 'a':
- goto nextclass;
- default:
- goto nextclass;
- }
- nexttry: str=next_a0(arg);
- }
- nextclass: ;
- }
-
- free(buf);
- return NULL;
-
- found:
- free(buf);
- return (char *)class;
- }
-
- char *
- getaction( char *class, char *action )
- {
- CLASS *cl;
- char *cur, *ind;
- int len;
-
- for( len=0; class[len] && (UBYTE)class[len]!=0xA0; len++ ) ;
- for( cl=CRoot; cl; cl=cl->next ) {
- if( strncmp( cur=cl->name,class,len+1 ))
- continue;
- do
- cur=index( cur,0xA0 );
- while( cur && *++cur!='a');
-
- if( cur && (cur=index( ++cur,0xA0 ))) {
- do {
- if( !(ind=index( ++cur,'=' )))
- return NULL;
- len=ind-cur;
- if( len==strlen(action) && !strncmp(action,cur,len))
- return ++ind;
- } while( cur=index(cur,0xA0) );
- }
- }
- return NULL;
- }
-
- int
- doaction( char *file, char *action, char *args )
- {
- char *class, *com, *c, *copy, *spc=index(file,' ');
-
- if( !(class=getclass(file)))
- return 10;
- if( !(com=getaction(class,action)))
- return 11;
- if( c=index(com,0xA0) )
- *c=0;
- copy=salloc( strlen(com)+strlen(file)+strlen(args)+7 );
- sprintf(copy,spc?"%s \"%s\" %s":"%s %s %s", com, file, args);
- execute(copy);
- free(copy);
- if( c )
- *c=0xA0;
- return 0;
- }
-
- void *
- salloc( int len )
- {
- void *ret;
-
- if( !len ) len++;
-
- if( !(ret=malloc(len))) {
- fprintf(stderr,"Out of memory -- exiting\n");
- main_exit( 20 );
- }
- return ret;
- }
-
- void *
- SAllocMem( long size, long req )
- {
- void *ret;
-
- if( !(ret=AllocMem(size,req))) {
- fprintf(stderr,"Out of memory -- exiting\n");
- main_exit( 20 );
- }
- return ret;
- }
-