home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume8 / mdcopy / part01 / democopy.c next >
Encoding:
C/C++ Source or Header  |  1989-11-02  |  4.6 KB  |  207 lines

  1. /*
  2.  * democopy    copy a file to/from multiple diskettes.
  3.  *
  4.  * This is a sample program used to illustrate the multi-disk i/o
  5.  * (mdio) package.  The prompt routines are used to check for the
  6.  * continuation of a file.  These are guaranteed to be called
  7.  * after no more bytes can be transferred to/from a file.
  8.  *
  9.  * When writing a file, after a diskette is full, the file is closed
  10.  * and the `output' prompt routine is called.  This creates an empty
  11.  * file with an extension of .TBC (to-be-continued), and asks for the
  12.  * next diskette.
  13.  *
  14.  * When reading a file, at EOF, the `at eof' function is called.
  15.  * This looks for a file with a .TBC extension, and if found returns
  16.  * FALSE since we are not really at EOF.  If this file is NOT found
  17.  * then we are really at EOF, so TRUE is returned.
  18.  *
  19.  * After the input file is closed, the `input' prompt routine is
  20.  * called which asks the user to insert the next diskette for the file.
  21.  *
  22.  * Note:  using an extension can be ambiguous, but this is only a
  23.  *        sample program.
  24.  *
  25.  * March 1989    created by greg yachuk.  placed in the public domain.
  26.  */
  27. #include <stdio.h>
  28. #include <malloc.h>
  29. #include <string.h>
  30. #include <fcntl.h>
  31. #include <sys/types.h>
  32. #include <sys/stat.h>
  33. #include "mdiskio.h"
  34.  
  35. /* these two guys are global for debugging purposes */
  36. MDFILE *ip, *op;
  37.  
  38. main(argc, argv)
  39. int    argc;
  40. char  **argv;
  41. {
  42.     char    buf[BUFSIZ];
  43.     int    len;
  44.     int    inprompt();
  45.     int    ateof();
  46.     int    outprompt();
  47.  
  48.     if (argc != 3)
  49.     {
  50.         puts("usage: mdcopy srcfile dstfile");
  51.         exit(1);
  52.     }
  53.  
  54.     if ((ip = mdopen(argv[1], "rb", NULL, 0)) == NULL)
  55.     {
  56.         perror(argv[1]);
  57.         exit(2);
  58.     }
  59.  
  60.     if ((op = mdopen(argv[2], "wb", NULL, 0)) == NULL)
  61.     {
  62.         perror(argv[2]);
  63.         exit(3);
  64.     }
  65.  
  66.     /* set buffer sizes to 16K each */
  67.  
  68.     mdsetbuf(ip, 16*1024);
  69.     mdsetbuf(op, 16*1024);
  70.  
  71.     /* override the default "prompt" routines */
  72.  
  73.     mdfnateof(ip, ateof);
  74.     mdfnprompt(ip, inprompt);
  75.     mdfnprompt(op, outprompt);
  76.  
  77.     /* and copy away... */
  78. #ifdef    PROFILE
  79.     PRFstart((long far *) main);
  80. #endif
  81.     while (!mdeof(ip))
  82.     {
  83.         len = mdread(buf, sizeof (char), sizeof buf, ip);
  84.         if (mdwrite(buf, sizeof (char), len, op) != len)
  85.             break;
  86.     }
  87. #ifdef    PROFILE
  88.     PRFstop();
  89. #endif
  90.     /* alternative copy... */
  91.  
  92.     while (!mdeof(ip) && !mdeof(op))
  93.         mdputc(mdgetc(ip), op);
  94.  
  95.     /* gotta make sure we close, cause this flushes the buffers */
  96.  
  97.     mdclose(ip);
  98.     mdclose(op);
  99.  
  100.     exit(0);
  101. }
  102.  
  103. /*
  104.  * contfnm -    construct the name of the `to-be-continued' marker file.
  105.  *        this is constructed from the basename with an extension
  106.  *        of `tbc' (to-be-continued).
  107.  */
  108. char   *
  109. contfnm(mdp)
  110. MDFILE *mdp;
  111. {
  112.     static char contfile[256];
  113.     char   *base;
  114.     char   *dotp;
  115.  
  116.     /* copy the basename */
  117.     strcpy(contfile, mdp->basename);
  118.  
  119.     /* strip off the drive and path from the tail */
  120.     if ((base = strrchr(contfile, '/')) == NULL)
  121.         base = contfile;
  122. #ifdef    DOS
  123.     /* this is DOS, y'know.  it allows both / and \ */
  124.     if ((dotp = strrchr(base, '\\')) == NULL)
  125.         dotp = base;
  126. #endif
  127.     /* scan for the '.' */
  128.     for (; *dotp && *dotp != '.'; ++dotp);
  129.  
  130.     /* and add the new extension */
  131.     *dotp++ = '.';
  132.     *dotp++ = 't';
  133.     *dotp++ = 'b';
  134.     *dotp++ = 'c';
  135.     *dotp = '\0';
  136.  
  137.     return (contfile);
  138. }
  139.  
  140. /*
  141.  * ateof -    this routine is called when EOF is reached while
  142.  *        reading the input file.  We check if we need to
  143.  *        ask for a new diskette, by checking for the existence
  144.  *        of a `.tbc' (to-be-continued) file.
  145.  */
  146. ateof(mdp, mode)
  147. MDFILE *mdp;
  148. int    mode;
  149. {
  150.     return (access(contfnm(mdp), 00));
  151. }
  152.  
  153. /*
  154.  * inprompt -    this routine is called when EOF of a diskette is
  155.  *        found, but there is supposed to be another diskette.
  156.  *        it prompts for the next diskette and waits for the
  157.  *        user to enter a carriage-return.
  158.  */
  159. inprompt(mdp)
  160. MDFILE *mdp;
  161. {
  162.     /* ask for another diskette, and wait for a response */
  163.     fputs("Please insert next diskette for ", stderr);
  164.     fputs(mdp->basename, stderr);
  165.     fputs(" and press ENTER...", stderr);
  166.  
  167.     while (getchar() != '\n');
  168.  
  169.     /* all ready to go with the next diskette */
  170.  
  171.     return (1);
  172. }
  173.  
  174. /*
  175.  * outprompt -    this routine is called when no more bytes can be
  176.  *        written to a file.  we create a `.tbc' (to-be-
  177.  *        continued) file on the same diskette.  Luckily,
  178.  *        DOS still has room to create a file when all the
  179.  *        disk space is gone.  Then ask for a new diskette.
  180.  */
  181. outprompt(mdp)
  182. MDFILE *mdp;
  183. {
  184.     char   *contfile;
  185.     int    fd;
  186.  
  187.     /* get the name of the to-be-continued file */
  188.     contfile = contfnm(mdp);
  189.  
  190.     /* create the to-be-continued file */
  191.     fd = open(contfile, O_CREAT|O_WRONLY, S_IREAD|S_IWRITE);
  192.     if (fd == -1)
  193.     {
  194.         perror(contfile);    /* something drastic went wrong */
  195.         return (0);        /* can't continue this file */
  196.     }
  197.  
  198.     close(fd);
  199.  
  200.     /* ask for another diskette and wait for a response */
  201.     _mdprompt(mdp);
  202.  
  203.     /* all ready to go with next diskette */
  204.  
  205.     return (1);
  206. }
  207.