home *** CD-ROM | disk | FTP | other *** search
- ; /*
- dcc -r -ms -v addpath.c -o addpath
- quit
- * ^^ This is PURE code!
- */
- /*
- * ADDPATH.C
- *
- * (C) Copyright 1992 by Olaf Seibert. All rights reserved.
- */
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <libraries/dosextens.h>
- #include <functions.h>
-
- struct path {
- BPTR next;
- BPTR lock;
- };
-
- int
- samelock(BPTR lock1, BPTR lock2)
- {
- struct FileLock *l1, *l2;
-
- l1 = BADDR(lock1);
- l2 = BADDR(lock2);
-
- return l1 == l2 ||
- (l1 != NULL &&
- l2 != NULL &&
- l1->fl_Volume == l2-> fl_Volume &&
- l1->fl_Key == l2->fl_Key);
- }
-
- char *
- dosalloc(int bytes)
- {
- long *mem;
-
- bytes += 4;
- mem = AllocMem(bytes, MEMF_PUBLIC | MEMF_CLEAR);
- if (mem) {
- *mem++ = bytes;
- }
- return (char *)mem;
- }
-
- void
- dosfree(char *mem)
- {
- mem -= sizeof(long);
- FreeMem(mem, *(long *)mem);
- }
-
- void
- usage(void)
- {
- static char blurb[] = "pends directory to path, if not already present";
-
- printf("Usage: addpath [-r] [-a] [-p] directory ...\n"
- " -r removes directory from path\n"
- " -a ap%s (default)\n"
- " -p pre%s\n", blurb, blurb);
- exit(10);
- }
-
- int
- main(int argc, char **argv)
- {
- struct Process *proc;
- struct CommandLineInterface *cli;
- struct path *path;
- BPTR *firstpath,
- *prevpath;
- char *dir;
- BPTR dirlock;
- enum { append, prepend, remove }
- action;
-
- proc = (struct Process *)FindTask(NULL);
- if (proc->pr_Task.tc_Node.ln_Type != NT_PROCESS) {
- exit(21);
- }
- cli = BADDR(proc->pr_CLI);
- if (cli == NULL) {
- exit(20);
- }
- firstpath = &cli->cli_CommandDir;
-
- if (argc == 1 || argv[1][0] == '?')
- usage();
-
- action = append;
- for (; dir = *++argv; ) {
- if (dir[0] == '-') {
- switch (dir[1]) {
- case 'a':
- action = append;
- break;
- case 'p':
- action = prepend;
- break;
- case 'r':
- action = remove;
- break;
- default:
- usage();
- break;
- }
- } else if (dirlock = Lock(dir, SHARED_LOCK)) {
- for (prevpath = firstpath; path = BADDR(*prevpath);
- prevpath = &path->next) {
- if (samelock(path->lock, dirlock))
- break;
- }
- if (path) {
- /* found it! */
- if (action == remove) {
- Forbid();
- *prevpath = path->next;
- Permit();
- UnLock(path->lock);
- dosfree(path);
- }
- } else if (action != remove) {
- /* didn't find it, so make it */
- path = dosalloc(sizeof(*path));
- path->lock = dirlock;
- dirlock = 0;
- if (action == prepend) {
- prevpath = firstpath;
- }
- Forbid();
- path->next = *prevpath;
- *prevpath = ((long) path) >> 2;
- Permit();
- }
- if (dirlock) {
- UnLock(dirlock);
- dirlock = 0;
- }
- } else {
- printf("Couldn't Lock '%s', error %ld\n", dir, IoErr());
- }
- }
- return 0;
- }
-