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

  1. ; /*
  2. dcc -r -ms -v addpath.c -o addpath
  3. quit
  4. *   ^^ This is PURE code!
  5. */
  6. /*
  7.  * ADDPATH.C
  8.  *
  9.  * (C) Copyright 1992 by Olaf Seibert. All rights reserved.
  10.  */
  11.  
  12. #include <exec/types.h>
  13. #include <exec/memory.h>
  14. #include <libraries/dosextens.h>
  15. #include <functions.h>
  16.  
  17. struct path {
  18.     BPTR    next;
  19.     BPTR    lock;
  20. };
  21.  
  22. int
  23. samelock(BPTR lock1, BPTR lock2)
  24. {
  25.     struct FileLock *l1, *l2;
  26.  
  27.     l1 = BADDR(lock1);
  28.     l2 = BADDR(lock2);
  29.  
  30.     return l1 == l2 ||
  31.        (l1 != NULL &&
  32.         l2 != NULL &&
  33.         l1->fl_Volume == l2-> fl_Volume &&
  34.         l1->fl_Key == l2->fl_Key);
  35. }
  36.  
  37. char *
  38. dosalloc(int bytes)
  39. {
  40.     long *mem;
  41.  
  42.     bytes += 4;
  43.     mem = AllocMem(bytes, MEMF_PUBLIC | MEMF_CLEAR);
  44.     if (mem) {
  45.     *mem++ = bytes;
  46.     }
  47.     return (char *)mem;
  48. }
  49.  
  50. void
  51. dosfree(char *mem)
  52. {
  53.     mem -= sizeof(long);
  54.     FreeMem(mem, *(long *)mem);
  55. }
  56.  
  57. void
  58. usage(void)
  59. {
  60.     static char blurb[] = "pends directory to path, if not already present";
  61.  
  62.     printf("Usage: addpath [-r] [-a] [-p] directory ...\n"
  63.        "       -r removes directory from path\n"
  64.        "       -a ap%s (default)\n"
  65.        "       -p pre%s\n", blurb, blurb);
  66.     exit(10);
  67. }
  68.  
  69. int
  70. main(int argc, char **argv)
  71. {
  72.     struct Process *proc;
  73.     struct CommandLineInterface *cli;
  74.     struct path    *path;
  75.     BPTR       *firstpath,
  76.            *prevpath;
  77.     char       *dir;
  78.     BPTR       dirlock;
  79.     enum { append, prepend, remove }
  80.            action;
  81.  
  82.     proc = (struct Process *)FindTask(NULL);
  83.     if (proc->pr_Task.tc_Node.ln_Type != NT_PROCESS) {
  84.     exit(21);
  85.     }
  86.     cli = BADDR(proc->pr_CLI);
  87.     if (cli == NULL) {
  88.     exit(20);
  89.     }
  90.     firstpath = &cli->cli_CommandDir;
  91.  
  92.     if (argc == 1 || argv[1][0] == '?')
  93.     usage();
  94.  
  95.     action = append;
  96.     for (; dir = *++argv; ) {
  97.     if (dir[0] == '-') {
  98.         switch (dir[1]) {
  99.         case 'a':
  100.         action = append;
  101.         break;
  102.         case 'p':
  103.         action = prepend;
  104.         break;
  105.         case 'r':
  106.         action = remove;
  107.         break;
  108.         default:
  109.         usage();
  110.         break;
  111.         }
  112.     } else if (dirlock = Lock(dir, SHARED_LOCK)) {
  113.         for (prevpath = firstpath; path = BADDR(*prevpath);
  114.          prevpath = &path->next) {
  115.         if (samelock(path->lock, dirlock))
  116.             break;
  117.         }
  118.         if (path) {
  119.         /* found it! */
  120.         if (action == remove) {
  121.             Forbid();
  122.             *prevpath = path->next;
  123.             Permit();
  124.             UnLock(path->lock);
  125.             dosfree(path);
  126.         }
  127.         } else if (action != remove) {
  128.         /* didn't find it, so make it */
  129.         path = dosalloc(sizeof(*path));
  130.         path->lock = dirlock;
  131.         dirlock = 0;
  132.         if (action == prepend) {
  133.             prevpath = firstpath;
  134.         }
  135.         Forbid();
  136.         path->next = *prevpath;
  137.         *prevpath = ((long) path) >> 2;
  138.         Permit();
  139.         }
  140.         if (dirlock) {
  141.         UnLock(dirlock);
  142.         dirlock = 0;
  143.         }
  144.     } else {
  145.         printf("Couldn't Lock '%s', error %ld\n", dir, IoErr());
  146.     }
  147.     }
  148.     return 0;
  149. }
  150.