home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
620.lha
/
AddPath
/
addpath.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-16
|
3KB
|
150 lines
; /*
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;
}