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

  1.  
  2. /*-----------------------------------------------------------------*/
  3. /*
  4.          Programme:     ARC2.C
  5.          ---------
  6.          Purpose:       Will "archive" files to the nominated disk
  7.          -------        and then set bit 7 of byte "t3" of the
  8.                         original file to show that it has been
  9.                         copied.
  10.  
  11.          Compiler:      BDS C V 1.50
  12.          --------
  13.          Written:       10/07/85
  14.          -------
  15.          Amended:       20/11/86  (for UTIL)
  16.          -------        28/11/86 to allow for the circumstance when
  17.                         the archive disk becomes full before the run
  18.                         is finished.
  19.  
  20.          Version:       2.0
  21.          -------
  22.  
  23.          Copyright 1986 - Cogar Computer Services Pty. Ltd.        */
  24. /*-----------------------------------------------------------------*/
  25. #include <bdscio.h>
  26. #include <pec.h>
  27. /*-----------------------------------------------------------------*/
  28. #define    VERSION "2.0\0"
  29. #define NAME    "ARCHIVE\0"
  30. /*-----------------------------------------------------------------*/
  31. main(argc, argv)    /* For Command Line processing             */
  32. int argc;
  33. char *argv[];
  34. {
  35. /*-----------------------------------------------------------------*/
  36. /*  Space reserved for variables used in programme                 */
  37. /*-----------------------------------------------------------------*/
  38.     char DRIVE;    /* The active drive                        */
  39.     char USER;    /* The User No. for this programme         */
  40.     int i, j, n, file_count, done_count; /* Counters           */
  41.     char c, d2;
  42.     int CPM;    /* To check the CP/M Version number        */
  43.     char OLD_DRIVE;    /* The drive at start of programme         */
  44.     char OLD_USER;    /* The User No. at start of programme      */
  45.     int  FD1, FD2;    /* For the open files                      */
  46.     char MY_DMA[128];    /* For data transfer               */
  47.     char NAME_BUF[1600];    /* For 50 file names               */
  48.     char BIG_BUF[16384];   /* For file transfer - 128 records  */
  49.     struct dpb *THIS;  /* For disk information                 */
  50.     int  DIRECTORY, SECTORS, offset;
  51.     char **skew_table; /* For sector translation               */
  52.     int  PHYS_SEC;
  53.     char in_file[15], out_file[15];
  54. /*-----------------------------------------------------------------*/
  55.     pec_clear();    /* Universal routine                       */
  56.     printf("%s - Version %s\n",NAME, VERSION);
  57.     printf("Copyright 1986 - Cogar Computer Services Pty.Ltd.\n\n");
  58. /*-----------------------------------------------------------------*/
  59. /*  First check the CP/M Version in use.   If it is less than
  60.     Version 2.0 then inform the user and terminate programme.      */
  61. /*-----------------------------------------------------------------*/
  62.  
  63.     CPM = get_cpm();    /* Obtain the CP/M version and No. */
  64.  
  65.     i = (CPM & 0xff) - 0x20; /* Mask off the MP/M bit          */
  66.  
  67.     if(i < 0)        /* Must be less than V 2.0         */
  68.     {
  69.     printf("This programme requires at least V 2.x of CP/M.\n");
  70.         printf("Sorry but it won't run for you.\n");
  71.         exit();
  72.     }
  73. /*-----------------------------------------------------------------*/
  74. /*  Now check the Command Line to see if any command was entered.
  75.     Other checks can also be used, as required but then it will be
  76.     necessary to change this coding.                               */
  77. /*-----------------------------------------------------------------*/
  78.     if(argc != 3)
  79.     {
  80. printf("This programme will copy files from the nominated drive\n");
  81. printf("to the ARCHIVE disk but will only accept those files which\n");
  82. printf("have not previously been copied.   It does this by checking\n");
  83. printf("the archive byte....byte 't3' of the file name.\n\n");
  84. printf("When it has copied the file across it will set bit 7 of t3\n");
  85. printf("in the particular file name to show that this file has now\n");
  86. printf("been archived.\n\n");
  87.  
  88.         printf("\tEnter the DRIVE to take files FROM - ");
  89.         DRIVE = toupper(getchar());
  90.         lines(2);
  91.         printf("\tEnter the DRIVE to copy files TO   - ");
  92.         d2 = toupper(getchar());
  93.     }
  94.     else if(argc == 3)
  95.     {
  96.         DRIVE = toupper(argv[1][0]);
  97.         d2 = toupper(argv[2][0]);
  98.     }
  99.     lines(2);
  100.     if(DRIVE == d2)
  101.     {
  102.         printf("Copying TO and FROM same disk is not allowed.");
  103.         exit();
  104.     }
  105. /*-----------------------------------------------------------------*/
  106. /*  Save the starting drive in case it is changed later.           */
  107. /*-----------------------------------------------------------------*/
  108.     OLD_DRIVE = get_default() + 0x41;
  109. /*-----------------------------------------------------------------*/
  110. /*  Save the starting User No. in case it is changed later.        */
  111. /*-----------------------------------------------------------------*/
  112.     OLD_USER = user_id(0xff);
  113. /*-----------------------------------------------------------------*/
  114. /*  Now check that the selected drives are available.              */
  115. /*-----------------------------------------------------------------*/
  116.     printf("You have nominated to copy FROM -  %c\n", DRIVE);
  117.     if(select_dsk(DRIVE) != 0)
  118.         exit();
  119.     printf("                           TO   -  %c\n", d2);
  120.     if(select_dsk(d2) != 0)
  121.         exit();
  122.     else printf("Both drives are acceptable.");
  123.     lines(2);
  124. /*-----------------------------------------------------------------*/
  125. /*  Get the pointer to the skew table for sector translation when
  126.     reading the Directory, and go back to the Copy drive.          */
  127. /*-----------------------------------------------------------------*/
  128.     if(!(skew_table = seldsk(DRIVE)))
  129.         exit();
  130.     if(select_dsk(DRIVE) != 0)
  131.         exit();
  132. /*-----------------------------------------------------------------*/
  133. /*  Get the information needed to read Directory track.            */
  134. /*-----------------------------------------------------------------*/
  135.     THIS = dpb_adr();
  136.     DIRECTORY = THIS->OFF;    /* The directory track             */
  137.     SECTORS   = THIS->SPT;  /* Records per track               */
  138.  
  139.     set_dma(&MY_DMA[0]);
  140.     set_trk(DIRECTORY);
  141.     file_count = done_count = offset = 0;
  142. /*-----------------------------------------------------------------*/
  143. /*  We now have to check for files to be archived.   When found
  144.     their names won't be in a suitable form to be used in the "open"
  145.     and "close" file functions available in BDS C.   It will be
  146.     necessary to first convert the names to suitable null-terminated
  147.     strings.                                                       */
  148. /*-----------------------------------------------------------------*/
  149.     printf("               FILES BEING ARCHIVED\n");
  150.     printf("               --------------------\n\n");
  151.  
  152.     for(i = 0; i < SECTORS; i++)
  153.     {
  154.         PHYS_SEC = biosh(16, i, *skew_table);
  155.         set_sec(PHYS_SEC);
  156.         setmem(&MY_DMA[0], 128, 0xe5);
  157. /*-----------------------------------------------------------------*/
  158. /*  Read one Directory sector into DMA buffer and then check if
  159.     any files are available for archiving.                         */
  160. /*-----------------------------------------------------------------*/
  161.         if(read_sec() != 0) /* Put information into DMA buffer */
  162.         {
  163.             printf("\nBad read of sector - %d", PHYS_SEC);
  164.             user_id(OLD_USER);
  165.             if(select_dsk(OLD_DRIVE) != 0)
  166.         printf("\nUnable to return to starting drive.");
  167.             exit();
  168.         }
  169.  
  170.         for(j = 0; j < 4; j++)
  171.         {
  172.             USER = MY_DMA[j*32];
  173.             c    = MY_DMA[j*32 + 11];
  174.  
  175.     if(USER != 0xe5 && USER == OLD_USER && c < 128)
  176.             {
  177.                 if(++file_count == 50)
  178.                 {
  179.     printf("There is a limit of 50 files which can be copied.\n");
  180.     printf("Your options are to run the programme again after\n");
  181.     printf("this run finishes....and so do the additional files.\n");
  182.     printf("Else you can go to ARCHIVE.C and alter the size of\n");
  183.     printf("the NAME_BUF to accomodate more files.\n\n");
  184.                 j = 4;
  185.                 i = SECTORS;
  186.                 }
  187.  
  188.     movmem(&MY_DMA[j*32], &NAME_BUF[offset], 32);
  189.                 offset = offset + 32;
  190.             }
  191.         }
  192.     }
  193. /*-----------------------------------------------------------------*/
  194. /*  Check to see whether we have anything to archive.   If not
  195.     then tell the user and terminate.                              */
  196. /*-----------------------------------------------------------------*/
  197.     if(file_count == 0)
  198.     {
  199.         user_id(OLD_USER);
  200.         if(select_dsk(OLD_DRIVE) != 0)
  201.         {
  202.             printf("\nUnable to return to starting drive.");
  203.             exit();
  204.         }
  205.     printf("No files altered since last time.\n");
  206.     printf("\nDo you want to run another utility - Y/N.");
  207. if((FD1 = open("UTIL.COM", 0)) != 0 && (c = toupper(getchar())) == 'Y')
  208. {
  209.     close(FD1);
  210.     exec("UTIL");
  211. }
  212.     exit();
  213.     }
  214. /*-----------------------------------------------------------------*/
  215. /*  Now open the files for reading/writing as the case may be and
  216.     copy them across using the available BDS C functions.          */
  217. /*-----------------------------------------------------------------*/
  218.     offset = 0;    /* Go back to start of name buffer         */
  219.  
  220.     for(i = 0; i < file_count; i++)
  221.     {
  222.         make_name(&NAME_BUF[offset], out_file);
  223.         out_file[0] = DRIVE;
  224.         make_name(&NAME_BUF[offset], in_file);
  225.         in_file[0]  = d2;
  226.  
  227. printf("Copying - %s\t\tTO - %s\n", &out_file[0], &in_file[0]);
  228.  
  229.         if((FD1 = open(&out_file[0], 0)) == -1)
  230.         {
  231.             printf("Unable to find - %s", &out_file[0]);
  232.             user_id(OLD_USER);
  233.             if(select_dsk(OLD_DRIVE) != 0)
  234.         printf("\nUnable to return to starting drive.");
  235.             exit();
  236.         }
  237.  
  238.         if((FD2 = creat(&in_file[0])) == -1)
  239.         {
  240.             printf("Unable to create file - %s\n", &in_file[0]);
  241.             printf("It may mean the disk is full, so try a new ");
  242.             printf("disk and run ARCHIVE again.\n\n");
  243.             close(FD1);
  244.             exit();
  245.         }
  246.  
  247. /*-----------------------------------------------------------------*/
  248. /*  The files are open for read/write so now transfer to the
  249.     archive disk.                                                  */
  250. /*-----------------------------------------------------------------*/
  251.         while(( n = read(FD1, &BIG_BUF[0], 128)) > 0)
  252.             if((write(FD2, &BIG_BUF[0], n)) != n)
  253.             {
  254.     printf("The ARCHIVE disk is probably full.   Try again with a ");
  255.     printf("fresh disk.\n\n");
  256.             close(FD2);
  257.             unlink(in_file);
  258.             i = file_count;
  259.             GOTO JMP1;
  260.             }
  261.         done_count++;
  262.         close(FD2);
  263. JMP1:        close(FD1);
  264.         offset = offset + 32;
  265.     }
  266. /*-----------------------------------------------------------------*/
  267. /*  Now set the archive bit for each of the files which was
  268.     copied.                                                        */
  269. /*-----------------------------------------------------------------*/
  270.     set_dma(&MY_DMA[0]);
  271.     set_trk(DIRECTORY);
  272.     n = 0;            /* The counter                     */
  273.  
  274.     for(i = 0; i < SECTORS; i++)
  275.     {
  276.         PHYS_SEC = biosh(16, i, *skew_table);
  277.         set_sec(PHYS_SEC);
  278.         setmem(&MY_DMA[0], 128, 0xe5);
  279. /*-----------------------------------------------------------------*/
  280. /*  Read one Directory sector into DMA buffer and then check the
  281.     files available for archiving.                                 */
  282. /*-----------------------------------------------------------------*/
  283.         if(read_sec() != 0) /* Put information into DMA buffer */
  284.         {
  285.             printf("\nBad read of sector - %d", PHYS_SEC);
  286.             user_id(OLD_USER);
  287.             if(select_dsk(OLD_DRIVE) != 0)
  288.         printf("\nUnable to return to starting drive.");
  289.             exit();
  290.         }
  291.  
  292.         for(j = 0; j < 4; j++)
  293.         {
  294.             USER = MY_DMA[j*32];
  295.             c    = MY_DMA[j*32 + 11];
  296.  
  297.     if(USER != 0xe5 && USER == OLD_USER && c < 128 && n < done_count)
  298.             {
  299.                 MY_DMA[j*32 + 11] = c | 0x80;
  300.                 n++;
  301.             }
  302.         }
  303.         write_sec();
  304.     }
  305.     printf("\n\nTotal No. of files archived  =  %d", done_count);
  306. /*-----------------------------------------------------------------*/
  307. /*  Before closing, make sure the User No. and the Drive No.
  308.     return to original settings.                                   */
  309. /*-----------------------------------------------------------------*/
  310.  
  311.     user_id(OLD_USER);
  312.     if(select_dsk(OLD_DRIVE) != 0)
  313.     {
  314.         printf("\nUnable to return to starting drive.");
  315.         exit();
  316.     }
  317.     printf("\nDo you want to run another utility - Y/N.");
  318. if((FD1 = open("UTIL.COM", 0)) != 0 && (c = toupper(getchar())) == 'Y')
  319. {
  320.     close(FD1);
  321.     exec("UTIL");
  322. }
  323. }
  324. /*-----------------------------------------------------------------*/
  325. /*            SUBROUTINES                                          */
  326. /*-----------------------------------------------------------------*/
  327. void make_name(buf, file_name)
  328. char *buf, file_name[15];
  329. {
  330.     char c, SW;
  331.     int i, j;
  332.     SW = TRUE;
  333.  
  334.     for(i = 1, j = 2; i < 12; i++)
  335.     {
  336.         c = buf[i] & 0xff;
  337.  
  338.         if(c != SPACE && j != 10 && SW)
  339.         {
  340.             file_name[j] = c;
  341.             j++;
  342.         }
  343.         else if(j == 10 && SW)
  344.         {
  345.             file_name[j] = '.';
  346.             j++;
  347.             file_name[j] = c;
  348.             j++;
  349.             SW = FALSE;
  350.         }
  351.         else if(c == SPACE && SW )
  352.         {
  353.             file_name[j] = '.';
  354.             j++;
  355.             SW = FALSE;
  356.         }
  357.         else if(i > 8 && !SW)
  358.         {
  359.             file_name[j] = c;
  360.             j++;
  361.         }
  362. /*-----------------------------------------------------------------*/
  363. /*  Knowledgable programmers will have noticed that this algorithmn
  364.     makes no provision for the circumstance when there is no TYPE.
  365.     e.g. for a file named, say, "PHIL".   Fortunately for us BDS C
  366.     doesn't care whether such a file is entered as -
  367.  
  368.               PHIL
  369.     or        PHIL.
  370.  
  371.     because it will convert it to the proper form anyway.   So I have
  372.     taken advantage of this to keep things simple.   Just thought
  373.     you'd be pleased to know.                                      */
  374. /*-----------------------------------------------------------------*/
  375.     }
  376.     file_name[j] = '\0';
  377.     file_name[1] = ':';
  378. }
  379. /*-----------------------------------------------------------------*/
  380. ---