home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / BDSC / BDSC-3 / CDIR.CQ / CDIR.C
Text File  |  2000-06-30  |  7KB  |  310 lines

  1. /*
  2.     CDIR.C - A CP/M 2.2 utility that allows operators to switch
  3. between user numbers by specifiying a name, rather than a number. This
  4. has the effect of simulating sixteen named directories in a convenient
  5. manner.
  6.  
  7.     When used in conjunction with ZCPR, and DUPUSR, CDIR can make
  8. CP/M a lot more livable until an operating system with a nice
  9. directory structure arrives.
  10.  
  11.     CDIR.C - (C) 1982 by Barry A. Dobyns.
  12.     Commercial use (sales) of this program is prohibited,
  13.     however, private use by individuals is encouraged.
  14.  
  15. -----------------------------------------------------------------
  16. USAGE:
  17.     cdir    <dirname>
  18.         changes to the user number that corresponds to dirname
  19.  
  20.     cdir /l
  21.         lists available dirnames and the corresponding numbers
  22.  
  23.     cdir /s <dirname> <number>
  24.         sets dirname to correspond to number
  25.  
  26.     cdir    /d <dirname>
  27.         deletes dirname
  28.  
  29.     cdir    /z
  30.         deletes all dirnames
  31.  
  32. -----------------------------------------------------------------
  33. Usage notes:
  34.  
  35.     CDIR keeps the correspondence table in a data area stored with
  36. the com file. a /s /z or /d operation forces CDIR to write itself back
  37. out to disk.
  38.  
  39.     Also, CDIR has a list of 'internal' names that are not kept in
  40. the list. This list includes names '0'-'15', 'a'-'f' and 'root'. Any
  41. name occuring in the internal list cannot be set or deleted.
  42.  
  43.     Remember to zero out the table before using CDIR.
  44.  
  45.     If using CDIR with ZCPR or any CP/M hack that searches other
  46. drives, be careful when using /s /d and /z. Also, CDIR restricts the
  47. use of these switches to user 0.
  48.  
  49. -----
  50.  
  51.     create:
  52.         A>cc cdir.c            ;compile
  53.         A>l2 cdir.c            ;link
  54.         A>noboot cdir.c        ;fix CP/M boot problem
  55.         A>cdir /z                ;zero out names table
  56.  
  57.     As best as I can determine, CP/M loses the user number set from
  58. within an application program iff the program terminates with a warm
  59. boot instead of a ret. In other words, in the code below, the program
  60. on the left leaves one in user 15, as expected. The program on the
  61. right leaves one in whatever the previously selected user area was.
  62.  
  63.         ;I win                    ;I lose
  64.         ;                        ;
  65.         org    100H                    org    100H
  66.         mvi    c,32                    mvi    c,32
  67.         mvi    e,15                    mvi    e,15
  68.         call    5                    call    5
  69.         ret                        jmp    0
  70.  
  71.     Anyone know why?? Therefore, CDIR must be run over with NOBOOT so
  72. that it returns and does not boot, otherwise it isn't very useful.
  73.  
  74. -----
  75. */
  76.  
  77. #define    ERROR    (-1)
  78. #define    FALSE    0
  79. #define    TRUE        1
  80. #define    CDIR        "CDIR.COM"
  81. #define    DIRMAX    50
  82.  
  83. struct entry {
  84.     char    dvalid;            /* whether or not it is active. */
  85.     char    dnumber;            /* the corresponding user number */
  86.     char    dname[20];        /* the directory name */
  87.     } dirlist[DIRMAX];
  88.  
  89. int tmp;
  90.  
  91. main(argc,argv)
  92.     int argc;
  93.     char **argv;
  94. {
  95.  
  96.     if (argc == 2) {                /* one argument */
  97.         if (match(argv[1],"/L")) {    /* either list */
  98.             list();
  99.             }
  100.         else if ( match(argv[1],"/Z")
  101.                 && inzero() ) {    /* or zero */
  102.             zero();
  103.             }
  104.         else switchto(argv[1]);        /* or switch to */
  105.         } /* end (argc == 2) */
  106.  
  107.     else if ( (argc == 3) && match(argv[1],"/D")
  108.             && inzero() ) {        /* delete */
  109.         delete(argv[2]);
  110.         } /* end (argc == 3) */
  111.  
  112.     else if ( (argc == 4) && match(argv[1],"/S")
  113.             && inzero() ) {        /* set */
  114.         set(argv[2],atoi(argv[3]));
  115.         }
  116.  
  117.     else usage();                    /* bad commands */
  118.  
  119.     puts("Done.");
  120.  
  121.     }    /* end of main */
  122.  
  123. list()    /* print a list of all the names */
  124. {
  125.     for (tmp = 0; tmp < DIRMAX; tmp++){
  126.         if (dirlist[tmp].dvalid)
  127.             printf("\t%s\t%d\n", dirlist[tmp].dname, dirlist[tmp].dnumber);
  128.         }
  129.  
  130.     }    /* end of list() */
  131.  
  132. zero()    /* zero (initialize) the table */
  133. {
  134.  
  135.     setmem(codend(),endext()-codend(),0);
  136.  
  137.     wrtcdir();
  138.  
  139.     }    /* end of zero() */
  140.  
  141. switchto(name)    /* switch to the user area associated with name */
  142. char *name;
  143. {
  144.     if ( (tmp=internal(name)) != ERROR ) {    /* if it's internal */
  145.         setuser(tmp);                    /* do it now */
  146.         return;
  147.         }
  148.  
  149.     else for (tmp = 0; tmp < DIRMAX; tmp++){ /* find it in list */
  150.         if ( (dirlist[tmp].dvalid) && match(name,dirlist[tmp].dname) ){
  151.             setuser(dirlist[tmp].dnumber);
  152.             return;
  153.             }
  154.         }
  155.     /* can't find name */
  156.     printf("Can't find name %s \n",name);
  157.     }    /* end of switchto(name) */
  158.  
  159.  
  160. delete(name)    /* remove name from list */
  161. char *name;
  162. {
  163.     if ( (tmp=internal(name)) != ERROR ) return;
  164.  
  165.     else for (tmp = 0; tmp < DIRMAX; tmp++){
  166.         if ( (dirlist[tmp].dvalid) && match(name,dirlist[tmp].dname) ){
  167.             dirlist[tmp].dvalid = FALSE;
  168.             wrtcdir();
  169.             return;
  170.             }
  171.         }
  172.     /* can't find name */
  173.     printf("Can't find name %s \n",name);
  174.     }    /* end of delete(name) */
  175.  
  176. set(name,number)    /* install name in list */
  177. char *name,number;
  178. {
  179.     if ( (tmp=internal(name)) != ERROR ) return;
  180.  
  181.     else for (tmp = 0; tmp < DIRMAX; tmp++){
  182.         if ( !(dirlist[tmp].dvalid) ){
  183.             dirlist[tmp].dvalid = TRUE;
  184.             dirlist[tmp].dnumber = number & 0x0f;
  185.             strcpy(dirlist[tmp].dname,name);
  186.             wrtcdir();
  187.             return;
  188.             }
  189.         }
  190.     /* no more space */
  191.     printf("No space to add name %s \n",name);
  192.     }    /* end of set(name,number) */
  193.  
  194. setuser(number)
  195. char number;
  196. {
  197.  
  198.     number &= 0x0F;        /* mask it */
  199.     bdos(32,number);        /* set it */
  200.     number = bdos(32,0xff);    /* make sure. */
  201.     printf("user %d\n",number);
  202.     }
  203.  
  204. wrtcdir()
  205. {
  206.     int nscts;
  207.  
  208.     nscts= (endext() + 128) / 128;
  209.  
  210.     if ( ( (tmp = open(CDIR,1)) == ERROR)
  211.         ||  ( seek(tmp,0,0) == ERROR )
  212.         ||  ( write(tmp,0x100,nscts) != nscts)
  213.         ||  ( close(tmp) == ERROR) )
  214.         printf("Fatal Error - cannot write %s !",CDIR);
  215.  
  216.     }    /* end of wrtcdir() */
  217.  
  218. usage()
  219. {
  220.     puts("USAGE:\n");
  221.     puts("\tcdir <dirname>\n");
  222.     puts("\t\tchanges to the user number that corresponds to dirname\n\n");
  223.     puts("\tcdir /l\n");
  224.     puts("\t\tlists available dirnames and the corresponding numbers\n\n");
  225.     puts("\tcdir /s <dirname> <number>\n");
  226.     puts("\t\tsets dirname to correspond to number\n\n");
  227.     puts("\tcdir /d <dirname>\n");
  228.     puts("\t\tdeletes dirname \n\n");
  229.     puts("\tcdir /z\n");
  230.     puts("\t\tdeletes all dirnames \n\n");
  231.     } /* end of usage() */
  232.  
  233. badob()
  234. {
  235.     return("(C) Copyright 1982 by Barry A. Dobyns");
  236.     } /* end of badob() */
  237.  
  238. match (s1, s2)                /* case-independent string equality */
  239.     char *s1, *s2;
  240. {
  241.     while (TRUE) {
  242.         if (toupper (*s1) != toupper (*s2)) return (FALSE);
  243.         if (!*s1++ || !*s2++) return (TRUE);
  244.         }
  245.     }
  246.  
  247. internal(name)
  248. char *name;
  249. {
  250.     if ( (match(name,"root")) ||  (match(name,"0")) )
  251.         return(0);
  252.  
  253.     else if (match(name,"1"))
  254.         return(1);
  255.  
  256.     else if (match(name,"2"))
  257.         return(2);
  258.  
  259.     else if (match(name,"3"))
  260.         return(3);
  261.  
  262.     else if (match(name,"4"))
  263.         return(4);
  264.  
  265.     else if (match(name,"5"))
  266.         return(5);
  267.  
  268.     else if (match(name,"6"))
  269.         return(6);
  270.  
  271.     else if (match(name,"7"))
  272.         return(7);
  273.  
  274.     else if (match(name,"8"))
  275.         return(8);
  276.  
  277.     else if (match(name,"9"))
  278.         return(9);
  279.  
  280.     else if (match(name,"9"))
  281.         return(9);
  282.  
  283.     else if (  (match(name,"10")) || (match(name,"a")) )
  284.         return(10);
  285.  
  286.     else if (  (match(name,"11")) || (match(name,"b")) )
  287.         return(11);
  288.  
  289.     else if (  (match(name,"12")) || (match(name,"c")) )
  290.         return(12);
  291.  
  292.     else if (  (match(name,"13")) || (match(name,"d")) )
  293.         return(13);
  294.  
  295.     else if (  (match(name,"14")) || (match(name,"e")) )
  296.         return(14);
  297.  
  298.     else if (  (match(name,"15")) || (match(name,"f")) )
  299.         return(15);
  300.  
  301.     else return(ERROR);
  302.     }    /* end of internal(name) */
  303.  
  304. inzero()    /* true if we're in user 0 */
  305. {
  306.     return(bdos(32,0xff) == 0);
  307.     }    /* end inzero() */
  308.  
  309. /* end of cdir.c */
  310.