home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************************
- * Program: Whereis (searches for a filename on your [hard]-disk) *
- * Version: 1.21 for AMIGA-Computers. Last-Update: Monday 07-Jan-1991 *
- * Whereis.c by R. Bless 1989/90. All Rights reserved! Program (exe) is *
- * free distributable. Compilable under Aztec 3.6a. *
- * ------------------------------ NOTE :---------------------------------- *
- * No redistribution of a changed source and/or executable without *
- * permission of the author!!! Please ask me first. See address below. *
- * ----------------------------------------------------------------------- *
- * I'm fed up with all 'whereis' or 'wo' utilities that I had, because the *
- * one is always case sensitive and can't be aborted, the other is *
- * horribly slow and can't handle wildcards >:-(! So here is my product *
- * which uses no recursive procedures. *
- * Written from 17-10-89 to 24-10-89 (first version then addups) *
- * (C)opyright by Roland Bless (Byteable Software Products) *
- ***************************************************************************/
- /*
- Any comments or bug-reports to:
-
- R o l a n d B l e s s |UUCP: rob@spirits.ka.sub.org
- Kriegsstrasse 129 |FAX: +49211623818 BTX:0211623818-0001
- 7500 Karlsruhe - FRG |---------spirits--in--the--material--world---------
- voice +49 721 857328 |"They built machines that they can't control" STING
-
- Please don't think that I'm not familiar with gotos or breaks and
- such things of not structured languages, but I won't go back to
- BASIC-Level with a jump here or there and you don't know where you are...
- In a mood I just decided to leave these things out... Maybe I should
- write in Pascal or Modula? :-) */
- /*
- future adds
- -s|u|D date search
- -l list format */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <exec/memory.h>
- #include <libraries/dos.h>
- #include <libraries/dosextens.h>
-
- #include "date.h" /* my own date function */
-
- #define MAXPATH 256 /* Maximum pathname length */
- #define MEMTYPE 0L /* Memtype: Fast or Chipmem */
- #define true 1 /* Right boolean values, because */
- #define false 0 /* typedef short BOOL, but TRUE= 1L! */
- #define ON true
- #define OFF false
-
- struct ListType
- {
- struct FileInfoBlock FIBlock;
- struct FileLock *FLock;
- struct ListType *prev;
- };
-
- /**** external functions & variables ****/
-
- extern int Enable_Abort;
-
- void *Lock();
- void *AllocMem();
- void *ParentDir();
- extern void date();
- struct Process *FindTask();
- struct MsgPort *CreatePort();
- long IsInteractive(), SetSignal();
- struct FileHandle *Input(), *Output();
- struct FileLock *CurrentDir();
-
- /***** globals *****/
-
- char MPath [256], c, casedep; /* Global PathName (MainPath) */
- WORD options= 0; /* options switches */
- WORD MPathPos= 0;
- struct StandardPacket *packet;
- struct MsgPort *replyport, *conid;
- struct Process *myprocess;
-
- char *prgname;
- enum { CASESENSITIVE=1, DIRSONLY=2, FILESONLY=4, LONGPATH=8 , SIZE=16,
- TIME=32, NOSUBDIRS=64, JUMPDIR=128 };
- /* switches go here */
-
- enum { NOMEM, NODIR, DESTROYEDENTRY, TOOMANYARGS, WRONGNAME, ILLEGALOPTION,
- NOPATTERN, NOINPUT, STRANGE, INFO, USAGE };
- /*** ErrorNumbers for ErrorHandle ***/
-
- char *Msg[]=
- { "FATAL ERROR: Not enough memory available!\n",
- "ERROR: Can't find that directory or device:",
- "ERROR: Destroyed entry! Couldn't examine this '",
- "ERROR: Can't handle so many arguments. See usage!\n",
- "ERROR: Please no path in the filename/pattern! See usage!\n",
- "ERROR: Illegal Option '",
- "ERROR: I've no filepattern to search for!\n",
- "ERROR: Input must be interactive! \n",
- "STRANGE ERROR: Something strange happend...!\n",
- "INFO: whereis V1.21 07-Jan-1991 by R. Bless.\n"
- }; /* Messages for ErrorHandle/Numbers */
-
- /******************/
-
- long
- Chk_Abort()
- {
- return 0L;
- }
-
- void ErrorHandle(ErrMsgNr)
- short ErrMsgNr;
- {
- if (ErrMsgNr != USAGE)
- fprintf(stderr, "%s- %s", prgname, Msg[ErrMsgNr]);
- else
- {
- fprintf(stderr, "usage: %s [-acdfijnpst] [dev:path] filename.", prgname);
- fprintf(stderr, " Wildcards *,? allowed.\n");
- }
- }
-
-
- int SwitchRaw(RawMode)
- BOOL RawMode;
-
- {
- replyport= (struct MsgPort *) CreatePort(NULL, NULL);
- if (!replyport)
- return 1;
-
- packet= (struct StandardPacket *)
- AllocMem((long)sizeof(*packet),MEMF_PUBLIC | MEMF_CLEAR);
- if (!packet)
- {
- DeletePort(replyport);
- return 1;
- }
-
- /* init DOS-Packet */
- packet->sp_Msg.mn_Node.ln_Name= (char *) &(packet->sp_Pkt); /* link packet- */
- packet->sp_Pkt.dp_Link= &(packet->sp_Msg); /* to message */
- packet->sp_Pkt.dp_Port= replyport; /* set-up reply port*/
- packet->sp_Pkt.dp_Type= ACTION_SCREEN_MODE; /* function */
-
- if (RawMode==ON)
- {
- packet->sp_Pkt.dp_Arg1= DOSTRUE;
- fflush(stdout);
- }
- else
- {
- packet->sp_Pkt.dp_Arg1= DOSFALSE;
- }
- PutMsg(conid,packet); /* send packet */
- WaitPort(replyport); /* wait for packet to come back */
- GetMsg(replyport); /* pull message */
- FreeMem(packet, (long) sizeof(*packet));
- DeletePort(replyport);
- return 0;
- }
-
-
- void printdate(ds)
- struct DateStamp *ds;
- {
- struct date mydate;
-
- date(&mydate, ds->ds_Days);
- fprintf(stdout," %02d-%02d-%02ld %02ld:%02ld:%02ld",
- mydate.day, mydate.month, mydate.year-1900,
- ds->ds_Minute/60L, ds->ds_Minute%60L, ds->ds_Tick/50L);
- }
-
-
- void Append(s, root) /* Appends the dirname to MPath (MainPath) */
- char *s;
- BOOL root;
-
- {
- int p;
-
- for (p= 0; s[p]!= '\0'; p++)
- MPath[MPathPos+p]= s[p];
- MPath[MPathPos+p++]= root==true ? ':' : '/';
- MPath[MPathPos+p]= '\0';
- MPathPos+=p;
- }
-
-
- void InsertPath(s, root) /* Inserts a dirname into MPath */
- char *s;
- struct FileLock *root;
-
- {
- int p,len;
-
- len= strlen(s)+1;
- for (p= MPathPos; p >= 0; p--)
- MPath[p+len]= MPath[p];
- MPathPos+=len;
- for (p= 0; s[p] != '\0'; p++)
- MPath[p]= s[p];
-
- MPath[p]= root==NULL ? ':' : '/';
- }
-
-
- void Cut() /* Removes the last dirname from MPath */
- {
- if (MPathPos) --MPathPos;
- while (--MPathPos>=0 && MPath[MPathPos] != '/' && MPath[MPathPos] != ':');
- MPath[++MPathPos]= '\0';
- }
-
-
- struct FileLock *FindRoot(FL) /* Climbs up to root-directory */
- struct FileLock *FL;
-
- {
- struct FileLock *PL;
-
- PL= FL;
- while (FL= ParentDir(FL))
- {
- UnLock(PL);
- PL=FL;
- }
- return PL;
- }
-
-
- long GetFullPath(path) /* Get the full pathname */
- char *path;
-
- {
- struct FileLock *FL, *PL;
- struct FileInfoBlock *FIB;
- BOOL Error= false;
-
- FIB= (struct FileInfoBlock *)
- AllocMem ((long) sizeof(struct FileInfoBlock), MEMTYPE);
-
- if (!FIB)
- {
- ErrorHandle(NOMEM);
- Error= true;
- }
- else
- if (!(FL= (struct FileLock *) Lock(path, (ULONG) ACCESS_READ)))
- {
- ErrorHandle(NODIR);
- fprintf(stderr," %s\n", path);
- Error= true;
- }
-
- while (FL && !Error)
- {
- if (!Examine(FL, FIB))
- {
- ErrorHandle(DESTROYEDENTRY);
- fprintf(stderr,"%s'. Very strange!\n", path);
- Error= true;
- }
- else
- {
- InsertPath(FIB->fib_FileName, PL= ParentDir(FL));
- UnLock (FL);
- FL= PL;
- }
- }
- if (FIB) FreeMem (FIB,(long) sizeof(struct FileInfoBlock));
- if (FL) UnLock (FL);
- return Error;
- }
-
-
- /* Wildcard handling, new routine since V1.19 */
-
- BOOL
- Match(s, fpat)
- register char *s,*fpat;
- {
- while (*fpat!='\0')
- {
- if (*fpat == '*')
- {
- while (*fpat=='*' || *fpat=='?')
- {
- fpat++; /* skip following wildcards, until letter or \0 */
- }
- if (*fpat!='\0') /* letter/pattern detected! */
- while (*s!='\0' && (*s&casedep) != (*fpat&casedep))
- s++;
- else
- while (*s!='\0') /* ingore all chars till end */
- s++;
- }
- else
- if (*fpat == '?')
- {
- fpat++; /* Just ignore that char */
- if (*s!='\0') s++;
- }
- else
- if ((*s&casedep) == (*fpat&casedep))
- {
- register char *stmp=s,*ptmp=fpat;
-
- /* test whether sub-string matches or not */
- while (*stmp!='\0' && ((*stmp&casedep) == (*ptmp&casedep)))
- {
- stmp++;ptmp++;
- }
- if (*stmp=='\0' || *ptmp=='*' || *ptmp=='?' || *ptmp=='\0')
- {
- fpat=ptmp;s=stmp; /* it does! next wildcard or so... */
- }
- else
- {
- s++;
- while (*s!='\0' && (*s&casedep) != (*fpat&casedep)) s++;
- }
- }
- else
- return false;
- }
- return (*s=='\0' ? true : false);
- }
-
-
- /* Now comes the main-stuff!!! */
-
- BOOL Search (path, fpat) /* not recursive! */
- char *path, *fpat;
-
- {
- struct FileLock *FL= NULL;
- struct FileInfoBlock *FIB= NULL;
- struct ListType *LChainP= NULL, *OldLChainP= NULL;
-
- BOOL Error= false;
- char cbuf;
- int p;
-
- casedep= (options & CASESENSITIVE) ? 0xFF : 0x5F; /* Mask for match() */
-
- if (!fpat)
- {
- ErrorHandle(WRONGNAME);
- Error= true;
- }
- else
- if (path)
- {
- if (options & LONGPATH)
- Error= GetFullPath(path); /* Full-Pathname */
- else
- { /* "short pathname" */
- int p;
-
- for (p= 0; path[p]!= '\0'; p++)
- MPath[MPathPos+p]= path[p];
-
- if (p>0)
- {
- p--;
- if (MPath[MPathPos+p]!='/' && MPath[MPathPos+p]!=':')
- {
- p++; MPath[MPathPos+p]= '/';
- }
- p++;
- }
- else
- MPathPos= 0;
-
- MPath[MPathPos+p]= '\0';
- MPathPos+= p;
- }
- }
-
- if (!Error)
- {
- LChainP= (struct ListType *)
- AllocMem ((long) sizeof(struct ListType), MEMTYPE);
-
- if (!LChainP)
- {
- ErrorHandle(NOMEM);
- Error= true;
- }
- else
- {
- FIB= &LChainP->FIBlock;
-
- if (!(FL= (struct FileLock *) Lock(MPath, (ULONG) ACCESS_READ)))
- {
- ErrorHandle(NODIR);
- fprintf(stderr," %s\n", MPath);
- Error= true;
- }
- else
- {
- if (!path)
- FL= FindRoot(FL);
-
- if (!Examine(FL, FIB))
- {
- ErrorHandle(DESTROYEDENTRY);
- fprintf(stderr,"%s'. Very strange!\n", path);
- Error= true;
- }
- else
- if (!path) Append(FIB->fib_FileName, true);
-
- if (!Error)
- while (FL)
- {
- while (FL && ExNext(FL, FIB) && !Error)
- {
- if (Match(FIB->fib_FileName, fpat)) /*Compare filename&pattern*/
- {
- BOOL found= false;
-
- if (FIB->fib_DirEntryType >= 0L) /** => it is a dirname **/
- {
- if (!(options & FILESONLY))
- {
- fprintf(stdout, "%s%s", MPath, FIB->fib_FileName);
-
- if (options & SIZE)
- fprintf(stdout, " (dir) ");
-
- if (options & TIME)
- printdate(&(FIB->fib_Date));
- fprintf(stdout, "\n");
- if (options & JUMPDIR)
- found= true;
- }
- }
- else /** => it is a filename **/
- if (!(options & DIRSONLY))
- {
- fprintf(stdout, "%s%s", MPath, FIB->fib_FileName);
-
- if (options & SIZE)
- fprintf(stdout, " %ld",FIB->fib_Size);
- if (options & TIME)
- printdate(&(FIB->fib_Date));
- fprintf(stdout, "\n");
- if (options & JUMPDIR)
- found= true;
- }
- if (found)
- {
- if (SwitchRaw(ON))
- Error= true;
- else
- {
- int c;
-
- fprintf(stderr,"Change to that dir? [yNq]:");
- c= getchar();
- fprintf(stderr,"%c\n", c);
- SwitchRaw(OFF);
-
- if (toupper(c)=='Y')
- {
- struct FileLock *CDL;
- struct CommandLineInterface *CLI;
- char *i;
- int p;
-
- if (FIB->fib_DirEntryType >= 0L)
- Append(FIB->fib_FileName, false);
- /* if Directory found append it to mpath, cause we'll: */
-
- /* change the current dir */
-
- CDL=(struct FileLock *) Lock(MPath, (ULONG) ACCESS_READ);
- if (!CDL)
- {
- ErrorHandle(STRANGE);
- Error= true;
- }
- CDL= CurrentDir(CDL);
- UnLock(CDL);
- /* The new-lock must be retained and can't be unlocked,
- the old one must be unlocked */
-
- CLI=(struct CommandLineInterface *)
- BADDR(myprocess->pr_CLI);
- i= (char *) ((CLI->cli_SetName) << 2);
-
- /* Copy the new name to CLI */
- for (p=0; MPath[p]!='\0'; p++)
- *(i+p+1)= MPath[p];
- if (MPath[p-1]=='/')
- {
- *i= (char) (p-1);
- }
- else
- *i= (char) p;
-
- if (FIB->fib_DirEntryType >= 0L)
- Cut();
-
- Error= true;
- }
- if (toupper(c)=='Q')
- {
- Error= true;
- fprintf(stdout,"Quit!\n");
- }
- }
- }
- }
-
- if (FIB->fib_DirEntryType >= 0L) /* Dirname? Climb down the tree */
- {
- if (!(options & NOSUBDIRS))
- {
- Append(FIB->fib_FileName, false);
- LChainP->FLock= FL;
- LChainP->prev = OldLChainP;
- OldLChainP= LChainP;
- cbuf= MPath[MPathPos-1]; MPath[MPathPos-1]= '\0';
- FL=(struct FileLock *) Lock(MPath, (ULONG) ACCESS_READ);
- MPath[MPathPos-1]= cbuf;
- if (!FL)
- {
- ErrorHandle(STRANGE);
- Error= true;
- }
- else
- {
- LChainP= (struct ListType *) AllocMem
- ((long) sizeof(struct ListType), MEMTYPE);
-
- if (!LChainP)
- {
- ErrorHandle(NOMEM);
- Error= true;
- UnLock(FL); /* Free last Lock */
- LChainP= OldLChainP; /* To free the whole list */
- FL= OldLChainP->FLock; /* Get actual Lock */
- OldLChainP= OldLChainP->prev;
- }
- else
- {
- FIB= &LChainP->FIBlock;
- Examine(FL, FIB);
- }
- }
- }
- }
- } /* Climb-up-the-tree section*/
- if (SetSignal(NULL, NULL) & (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D))
- {
- SetSignal(NULL, (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D));
- if (!Error)
- {
- fprintf(stderr, "** BREAK **\n"); /* Just print one break */
- Error= true;
- }
- }
- if (LChainP) /* Is there still an entry? */
- {
- UnLock(FL); /* Free actual Lock */
- Cut();
- FreeMem (LChainP, (long) sizeof(struct ListType));
- if (OldLChainP) /* Get next entry to free,climb up list */
- {
- FL = OldLChainP->FLock;
- FIB= &OldLChainP->FIBlock;
- LChainP= OldLChainP;
- OldLChainP= OldLChainP->prev;
- }
- else /* Last entry reached */
- {
- FL= NULL;
- LChainP= NULL;
- }
- }
- else
- FL= NULL; /* No more entries? -> leave while loop */
- }
- }
- }
- }
- if (LChainP) FreeMem (LChainP,(long) sizeof(struct ListType));
- if (OldLChainP) FreeMem (OldLChainP,(long) sizeof(struct ListType));
- if (FL) UnLock (FL);
-
- return Error;
- }
-
- /******* main(), what else? *******/
-
- main(argc, argv)
- int argc;
- char **argv;
-
- {
- int i1, i2, findx= 0;
- char *args[2], *patharg=NULL, *filepattern=NULL;
-
-
- Enable_Abort= 0; /*** No Ctrl-C please!!! ***/
- args[0]= args[1]= NULL;
- prgname= *argv;
-
- SetSignal(NULL, (SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D)); /*** Clear Ctrl-D signal ***/
-
- if (argc == 1)
- {
- ErrorHandle(USAGE);
- exit(RETURN_OK);
- }
-
- for (i1= 1; i1 != argc; i1++)
- {
- if (*argv[i1] == '-')
- for (i2= 1; argv[i1][i2] != '\0'; i2++)
- {
- switch (argv[i1][i2])
- {
- case 'a': options|= SIZE | TIME;
- break;
-
- case 'c': options|= CASESENSITIVE;
- break;
-
- case 'd': options|= DIRSONLY;
- break;
-
- case 'f': options|= FILESONLY;
- break;
-
- case 'i': ErrorHandle(USAGE);
- ErrorHandle(INFO);
- exit(RETURN_OK);
- break;
-
- case 'j': if (IsInteractive(Input()))
- {
- myprocess= (struct Process *) FindTask(NULL);
- conid = (struct MsgPort *) myprocess->pr_ConsoleTask;
- /* get con-handler */
- options|= (JUMPDIR | LONGPATH);
- }
- else
- {
- ErrorHandle(NOINPUT);
- exit(RETURN_FAIL);
- }
-
- break;
-
- case 'n': options|= NOSUBDIRS;
- break;
-
- case 'p': options|= LONGPATH;
- break;
-
- case 's': options|= SIZE;
- break;
-
- case 't': options|= TIME;
- break;
-
-
- default : ErrorHandle(ILLEGALOPTION);
- fprintf(stderr,"%c' !\n", argv[i1][i2]);
- ErrorHandle(USAGE);
- exit (RETURN_ERROR);
- break;
- }
- }
- else
- {
- if (findx > 1)
- {
- ErrorHandle(TOOMANYARGS);
- exit (RETURN_ERROR);
- }
- else
- {
- args[findx]= argv[i1]; findx++;
- }
- }
- }
-
- if (findx==0)
- {
- ErrorHandle(NOPATTERN);
- ErrorHandle(USAGE);
- exit(RETURN_ERROR);
- }
- for (i1= 0; i1 < 2; i1++)
- {
- if (args[i1] != NULL)
- {
- for (i2= 0; (c= args[i1][i2]) != '\0' && c != ':' && c != '/';i2++);
-
- if (c != '\0')
- patharg= args[i1];
- else
- filepattern= args[i1];
- }
- }
- if (findx == 2 && !patharg)
- {
- patharg= args[0];
- filepattern= args[1];
- }
-
- if (Search(patharg, filepattern) == true)
- {
- fprintf(stderr, "%s-- Aborted!\n", prgname);
- exit(RETURN_ERROR);
- }
- }
-