home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 225_01 / user2.c < prev    next >
Text File  |  1987-06-09  |  14KB  |  383 lines

  1.  
  2. /*-----------------------------------------------------------------*/
  3. /*       STANDARD HEADER FOR BDS C PROGRAMMES
  4.          ------------------------------------
  5.  
  6.          Programme:     USER2.C
  7.          ---------
  8.          Purpose:       This programme will delete all inactive
  9.          -------        entries from the directory and then re-write
  10.                         the directory in (almost) alphabetical order.
  11.  
  12.          Written:       11/05/86
  13.          -------
  14.          Amended:       06/11/86
  15.          -------
  16.          Version:       2.0
  17.          -------
  18.  
  19.          Copyright 1986 - Cogar Computer Services Pty. Ltd.        */
  20. /*-----------------------------------------------------------------*/
  21. #include <bdscio.h>
  22. #include <pec.h>
  23. /*-----------------------------------------------------------------*/
  24. #define    VERSION "2.0\0"
  25. #define NAME    "USER2\0"
  26. /*-----------------------------------------------------------------*/
  27.  
  28. main(argc, argv)    /* For Command Line processing             */
  29. int argc;
  30. char *argv[];
  31. {
  32. /*-----------------------------------------------------------------*/
  33. /*  Space reserved for variables used in programme                 */
  34. /*-----------------------------------------------------------------*/
  35.     int i, j, k, l;
  36.     char c;
  37.     int CPM;    /* To check the CP/M Version number        */
  38.     char DRIVE;    /* The active drive                        */
  39.     char OLD_DRIVE;    /* The starting drive No.                  */
  40.     char OLD_USER;    /* The User No. at start of programme      */
  41.     char FROM_USER;    /* User area to take file from             */
  42.     char TO_USER;    /* User area to put file to                */
  43.     char my_dma[128];    /* The dma buffer to use           */
  44.     char my_file[15];
  45.     char filename[12];
  46.     char READING, FOUND, FLAG;
  47.     int  FD;    /* The file descriptor                     */
  48.     char out_buf[128];
  49.     char **skew_table;
  50.     int  PHYS_SEC;    /* The physical sector to read/write       */
  51.     unsigned STORAGE;    /* The size of the big buffer      */
  52.     struct dpb *THIS;    /* Disk parameter information      */
  53.     int  DIRECTORY;    /* The directory track                     */
  54.     int  SECTORS;    /* Sectors per track                       */
  55.     int  ENTRIES;    /* The active entries in directory         */
  56.     char *BIG_BUF, *infile;
  57. /*-----------------------------------------------------------------*/
  58.     pec_clear();    /* Universal routine                       */
  59.     printf("%s - Version %s\n",NAME, VERSION);
  60.     printf("Copyright 1986 - Cogar Computer Services Pty.Ltd.\n");
  61.     printf("----------------------------------------------------------\n");
  62.     printf("This programme will copy a nominated programme to another\n");
  63.     printf("User Area, from the present User Area.   At the same time\n");
  64.     printf("as it does this it will also 'clean up' the directory\n");
  65.     printf("tracks by removing any inactive (0xe5) entries, and will\n");
  66.     printf("then sort the active entries into (approximate) alphabetical\n");
  67.     printf("order.\n");
  68.     printf("----------------------------------------------------------\n");
  69. /*-----------------------------------------------------------------*/
  70. /*  First check the CP/M Version in use.   If it is less than
  71.     Version 2.0 then inform the user and terminate programme.      */
  72. /*-----------------------------------------------------------------*/
  73.  
  74.     CPM = get_cpm();    /* Obtain the CP/M version and No. */
  75.  
  76.     i = (CPM & 0xff) - 0x20; /* Mask off the MP/M bit          */
  77.  
  78.     if(i < 0)        /* Must be less than V 2.0         */
  79.     {
  80.     printf("This programme requires at least V 2.x of CP/M.\n");
  81.         printf("Sorry but it won't run for you.\n");
  82.         exit();
  83.     }
  84. /*-----------------------------------------------------------------*/
  85. /*  The CP/M Version is OK, so save the starting User No. and the
  86.     starting Drive No. in case either is changed later.            */
  87. /*-----------------------------------------------------------------*/
  88.  
  89.     OLD_USER = user_id(0xff);
  90.     OLD_DRIVE = get_default() + 0x41;
  91.  
  92. /*-----------------------------------------------------------------*/
  93. /*  Now check the Command Line to see if anything was entered.
  94.     We are looking for the file name to transfer to another user
  95.     area and the drive code if the current drive isn't being used  */
  96. /*-----------------------------------------------------------------*/
  97.     if(argc != 2)
  98.     {
  99.         printf("You have to enter the FILE you wish to transfer.\n");
  100.         printf("The required style is -\n\n");
  101.         printf("\t\t[dr:]filename.type\n\n");
  102.         printf("where 'dr:' is the optional drive code.   If you ");
  103.         printf("don't\n");
  104.         printf("specify a drive then the current drive is used\n");
  105.         infile = gets(my_file);
  106.     }
  107.     else if(argc == 2)
  108.         infile = argv[1];
  109.     up_str(infile);        /* Make name upper case letters    */
  110.     lines(2);
  111.  
  112. /*-----------------------------------------------------------------*/
  113. /*  Now check for the drive to be used.                            */
  114. /*-----------------------------------------------------------------*/
  115.     if(infile[1] == ':')    /* Then we have a drive code       */
  116.         DRIVE = toupper(infile[0]);
  117.     else DRIVE = GET_DEFAULT() + 65;
  118. /*-----------------------------------------------------------------*/
  119. /*  Check that the selected drive is available/on-line.   If not
  120.     then terminate the programme.   You may need to add a message
  121.     about what is going on if your version of CP/M doesn't do
  122.     this automatically, as mine does.                              */
  123. /*-----------------------------------------------------------------*/
  124.     if(!(skew_table = seldsk(DRIVE)))
  125.         exit();        /* Must be something wrong         */
  126.     if(select_dsk(DRIVE) != 0)
  127.         exit();
  128.     printf("          For Drive - %c\n", DRIVE);
  129.     printf("          -------------\n\n");
  130. /*-----------------------------------------------------------------*/
  131. /*  The next job is to put the file name in the form which it will
  132.     appear in the directory.                                       */
  133. /*-----------------------------------------------------------------*/
  134.     setmem(&filename[0], 11, 0x20);
  135.     if(infile[1] != ':')    /* No drive code given             */
  136.         j = 0;
  137.     else j = 2;        /* Drive code given                */
  138.  
  139.     for(i = 0; i < 11; i++)
  140.     {
  141.         if(infile[j] != '.' && i < 8)
  142.         {
  143.             filename[i] = infile[j];
  144.             j++;
  145.         }
  146.         else if(infile[j] == '.' && i < 8)
  147.             filename[i] = SPACE;
  148.         else if(i > 7)
  149.         {
  150.             j++;
  151.         if(isalnum(infile[j]))
  152.             filename[i] = infile[j];
  153.         else filename[i] = 0x20;
  154.         }
  155.     }
  156.     filename[i] = '\0';
  157.     printf("The parsed file name is ==> %s\n", filename);
  158.  
  159. /*-----------------------------------------------------------------*/
  160. /*  Everything appears to be OK, so now ask the user to nominate
  161.     the user area he/she wishes the file to be put into.           */
  162. /*-----------------------------------------------------------------*/
  163.     printf("Which User Area is the file now in - ");
  164.     scanf("%d", &FROM_USER);
  165.     lines(2);
  166.     printf("Which USER No. do you want this file to go to -\n");
  167.     THIS = dpb_adr();
  168.     scanf("%d", &TO_USER);
  169.     SECTORS = THIS->SPT;
  170.     TO_USER = TO_USER & 0xff;
  171.     if(TO_USER == FROM_USER)
  172.     {
  173.         printf("You can't copy to same User Area.");
  174.         exit();
  175.     }
  176.     lines(2);
  177. /*-----------------------------------------------------------------*/
  178. /*  Now do some checking to see -
  179.  
  180.          A.   Whether the file exists in the first user area; and
  181.  
  182.          B.   Whether or not it already exists in the nominated
  183.               user area.                                           */
  184. /*-----------------------------------------------------------------*/
  185.     user_id(FROM_USER);    /* Go to first User Area           */
  186.     if((FD = open(infile,0)) == -1)
  187.     {
  188.         printf("Unable to find - %s\n", infile);
  189.         user_id(OLD_USER);
  190.         exit();
  191.     }
  192.     else printf("OK, have found - %s\n", infile);
  193.     close(FD);
  194.     user_id(TO_USER);    /* Go to nominated user area for check     */
  195.     if((FD = open(infile,0)) != -1)
  196.     {
  197. printf("The file - %s  already exists in User Area - %d\n", infile, TO_USER);
  198.         user_id(OLD_USER);
  199.         exit();
  200.     }
  201. else printf("and it doesn't yet exist in User Area - %d\n\n",  TO_USER);
  202.     close(FD);
  203.     user_id(FROM_USER);    /* Return to first user area       */
  204. /*-----------------------------------------------------------------*/
  205. /*  Calculate the values we need to scan the directory.            */
  206. /*-----------------------------------------------------------------*/
  207.  
  208.     THIS      = dpb_adr();
  209.     DIRECTORY = THIS->OFF;
  210.     SECTORS   = THIS->SPT;
  211.  
  212.     set_dma(&my_dma[0]);    /* Create DMA buffer               */
  213.     set_trk(DIRECTORY);
  214.  
  215. /*-----------------------------------------------------------------*/
  216. /*  Read the directory track and count the number of active
  217.     entries.   This information is required for the size of
  218.     the big buffer.                                                */
  219. /*-----------------------------------------------------------------*/
  220.     printf("Counting the active directory entries.\n");
  221.     ENTRIES = 0;        /* Starting conditions             */
  222.     for(i = 0; i < SECTORS; i++)
  223.     {
  224.         PHYS_SEC = biosh(16, i, *skew_table);
  225.         set_sec(PHYS_SEC);
  226.         setmem(&my_dma[0], 128, 0xe5);
  227.         read_sec();    /* Put information into DMA buffer */
  228.  
  229.     for(j = 0; j < 4; j++)
  230.     {
  231.         if(my_dma[j*32] != 0xe5)
  232.             ENTRIES++;
  233.     }
  234.     }
  235.     printf("Present active entries (all extents) = %d\n", ENTRIES);
  236. /*-----------------------------------------------------------------*/
  237. /*  Now secure enough storage to hold all the active entries.      */
  238. /*-----------------------------------------------------------------*/
  239.     STORAGE = (((ENTRIES/4)*4) + 8)*32;
  240.     BIG_BUF = alloc(STORAGE);
  241.     setmem(BIG_BUF, STORAGE, 0xe5);    /* Clear the buffer        */
  242. /*-----------------------------------------------------------------*/
  243. /*  Then transfer the active entries to the big buffer.            */
  244. /*-----------------------------------------------------------------*/
  245.     set_trk(DIRECTORY);
  246.     j = 0;
  247.     for(i = 0; i < SECTORS; i++)
  248.     {
  249.         PHYS_SEC = biosh(16, i, *skew_table);
  250.         set_sec(PHYS_SEC);
  251.         setmem(&my_dma[0], 128, 0xe5);
  252.         read_sec();    /* Put information into DMA buffer */
  253.  
  254.         for(k = 0; k < 4; k++)
  255.         {
  256.             if(my_dma[k*32] != 0xe5)
  257.             {
  258.                 movmem(&my_dma[k*32], &BIG_BUF[j], 32);
  259.                 j = j + 32;
  260.             }
  261.         }
  262.     }
  263. /*-----------------------------------------------------------------*/
  264. /*  All the active entries are now in the big buffer so we can
  265.     erase the existing directory.   After this we find the file
  266.     to transfer to the nominated user area, add this to the end
  267.     of the big buffer then write the active entries back to the
  268.     directory track in (almost) alphabetical order.   This
  269.     completes the programme.                                       */
  270. /*-----------------------------------------------------------------*/
  271.     printf("Scrubbing old directory.\n");
  272.     for(i = 0; i < 1000; i++)
  273.         ;        /* Empty loop                      */
  274.     setmem(&my_dma[0], 128, 0xe5);
  275.     set_trk(DIRECTORY);
  276.     for(i = 0; i < SECTORS; i++)
  277.     {
  278.         set_sec(i);
  279.         write_sec();
  280.     }
  281. /*-----------------------------------------------------------------*/
  282. /*  Old directory erased.                                          */
  283. /*-----------------------------------------------------------------*/
  284.     FOUND   = FALSE;
  285.     setmem(&out_buf[0], 128, 0xe5);
  286.     l = 0;
  287.  
  288.     for(i = 0; i < ENTRIES*32; i = i + 32)
  289.     {
  290.         if(BIG_BUF[i] != 0xe5)
  291.         {
  292. if(compare(&filename[0], &BIG_BUF[i + 1], 11) == 1 && BIG_BUF[i] == FROM_USER)
  293.         {
  294.         movmem(&BIG_BUF[i], &out_buf[l], 32);
  295.         out_buf[l] = TO_USER;    /* Put into chosen area    */
  296.         l = l + 32;
  297.         FOUND = TRUE;
  298.         }
  299.         }
  300.     }
  301.     if(FOUND == FALSE)
  302.     {
  303.         printf("The file - %s  was not matched.\n", filename);
  304.         user_id(OLD_USER);
  305.     }
  306. /*-----------------------------------------------------------------*/
  307. /*  File located, so add to big buffer.                            */
  308. /*-----------------------------------------------------------------*/
  309.     if(FOUND == TRUE)
  310.         movmem(&out_buf[0], &BIG_BUF[ENTRIES*32], 128);
  311.  
  312. /*-----------------------------------------------------------------*/
  313. /*  Then write back the re-formatted directory entries.            */
  314. /*-----------------------------------------------------------------*/
  315.     printf("Writing re-formatted directory.\n");
  316.     set_trk(DIRECTORY);
  317.     k = 0;        /* Count of active files in DMA buffer     */
  318.     l = 0;        /* The directory sector to write           */
  319.  
  320.     for(c = 0x41; c < 0x60; c++)
  321.     {
  322.     for(i = 0; i < STORAGE; i = i + 32)
  323.     {
  324.     if(BIG_BUF[i + 1] == c)
  325.     {
  326.         movmem(&BIG_BUF[i], &my_dma[k*32], 32);
  327.         k++;
  328.         if(k == 4)
  329.         {
  330.             PHYS_SEC = biosh(16, l, *skew_table);
  331.             set_sec(PHYS_SEC);
  332.             write_sec();    /* Write to directory      */
  333.             l++;    /* Advance sector count            */
  334.             k = 0;
  335.             setmem(&my_dma[0], 128, 0xe5);
  336.         }
  337.     }
  338.     }
  339.     }
  340.     if(k > 0 && k < 4)
  341.     {
  342.         PHYS_SEC = biosh(16, l, *skew_table);
  343.         set_sec(PHYS_SEC);
  344.         write_sec();
  345.     }
  346.  
  347.     printf("Directory now re-written.");
  348.  
  349. /*-----------------------------------------------------------------*/
  350. /*  Before closing, make sure the User No. and Drive No. return
  351.     to original settings.                                          */
  352. /*-----------------------------------------------------------------*/
  353.     user_id(OLD_USER);
  354.     if(select_dsk(OLD_DRIVE) != 0)
  355.     {
  356.         printf("\nUnable to return to starting drive.");
  357.         exit();
  358.     }
  359.     printf("\n\nDo you want to run another utility - Y/N.");
  360. if((FD = open("UTIL.COM", 0)) != -1 && (c = toupper(getchar())) == 'Y')
  361. {
  362.     close(FD);
  363.     exec("UTIL");
  364. }
  365. else printf("\n\nReturning to CP/M.");
  366.  
  367. }
  368. /*-----------------------------------------------------------------*/
  369. char compare(s1, s2, n)
  370. char *s1, *s2;
  371. int n;
  372. {
  373.     int i;
  374.  
  375.     for(i = 0; i < n; i++)
  376.     {
  377.         if(toupper(s1[i]) != (toupper(s2[i]) & 0x7f))
  378.             return(0);
  379.     }
  380.     return(1);
  381. }
  382. /*-----------------------------------------------------------------*/                      */
  383. /*------------------------------