home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / bin / dd / position.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-28  |  4.9 KB  |  164 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Keith Muller of the University of California, San Diego and Lance
  7.  * Visser of Convex Computer Corporation.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37.  
  38. #ifndef lint
  39. static char sccsid[] = "@(#)position.c    5.3 (Berkeley) 8/5/91";
  40. #endif /* not lint */
  41.  
  42. #include <sys/types.h>
  43. #include <sys/stat.h>
  44. #include <sys/ioctl.h>
  45. #include <sys/mtio.h>
  46. #include <errno.h>
  47. #include <unistd.h>
  48. #include <string.h>
  49. #include "dd.h"
  50. #include "extern.h"
  51.  
  52. /*
  53.  * Position input/output data streams before starting the copy.  Device type
  54.  * dependent.  Seekable devices use lseek, and the rest position by reading.
  55.  * Seeking past the end of file can cause null blocks to be written to the
  56.  * output.
  57.  */
  58. void
  59. pos_in()
  60. {
  61.     register int bcnt, cnt, nr, warned;
  62.  
  63.     /* If not a character, pipe or tape device, try to seek on it. */
  64.     if (!(in.flags & (ISCHR|ISPIPE|ISTAPE))) {
  65.         if (lseek(in.fd, (off_t)(in.offset * in.dbsz), SEEK_CUR) == -1)
  66.             err("%s: %s", in.name, strerror(errno));
  67.         return;
  68.     }
  69.  
  70.     /*
  71.      * Read the data.  If a pipe, read until satisfy the number of bytes
  72.      * being skipped.  No differentiation for reading complete and partial
  73.      * blocks for other devices.
  74.      */
  75.     for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
  76.         if ((nr = read(in.fd, in.db, bcnt)) > 0) {
  77.             if (in.flags & ISPIPE) {
  78.                 if (!(bcnt -= nr)) {
  79.                     bcnt = in.dbsz;
  80.                     --cnt;
  81.                 }
  82.             } else
  83.                 --cnt;
  84.             continue;
  85.         }
  86.  
  87.         if (nr == 0) {
  88.             if (files_cnt > 1) {
  89.                 --files_cnt;
  90.                 continue;
  91.             }
  92.             err("skip reached end of input");
  93.         }
  94.  
  95.         /*
  96.          * Input error -- either EOF with no more files, or I/O error.
  97.          * If noerror not set die.  POSIX requires that the warning
  98.          * message be followed by an I/O display.
  99.          */
  100.         if (ddflags & C_NOERROR) {
  101.             if (!warned) {
  102.                 warn("%s: %s", in.name, strerror(errno));
  103.                 warned = 1;
  104.                 summary(0);
  105.             }
  106.             continue;
  107.         }
  108.         err("%s: %s", in.name, strerror(errno));
  109.     }
  110. }
  111.  
  112. void
  113. pos_out()
  114. {
  115.     register int cnt, n;
  116.     struct mtop t_op;
  117.  
  118.     /*
  119.      * If not a tape, try seeking on the file.  Seeking on a pipe is
  120.      * going to fail, but don't protect the user -- they shouldn't
  121.      * have specified the seek operand.
  122.      */
  123.     if (!(out.flags & ISTAPE)) {
  124.         if (lseek(out.fd,
  125.             (off_t)out.offset * out.dbsz, SEEK_SET) == -1)
  126.             err("%s: %s", out.name, strerror(errno));
  127.         return;
  128.     }
  129.  
  130.     /* If no read access, try using mtio. */
  131.     if (out.flags & NOREAD) {
  132.         t_op.mt_op = MTFSR;
  133.         t_op.mt_count = out.offset;
  134.  
  135.         if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)
  136.             err("%s: %s", out.name, strerror(errno));
  137.         return;
  138.     }
  139.  
  140.     /* Read it. */
  141.     for (cnt = 0; cnt < out.offset; ++cnt) {
  142.         if ((n = read(out.fd, out.db, out.dbsz)) > 0)
  143.             continue;
  144.  
  145.         if (n < 0)
  146.             err("%s: %s", out.name, strerror(errno));
  147.  
  148.         /*
  149.          * If reach EOF, fill with NUL characters; first, back up over
  150.          * the EOF mark.  Note, cnt has not yet been incremented, so
  151.          * the EOF read does not count as a seek'd block.
  152.          */
  153.         t_op.mt_op = MTBSR;
  154.         t_op.mt_count = 1;
  155.         if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
  156.             err("%s: %s", out.name, strerror(errno));
  157.  
  158.         while (cnt++ < out.offset)
  159.             if ((n = write(out.fd, out.db, out.dbsz)) != out.dbsz)
  160.                 err("%s: %s", out.name, strerror(errno));
  161.         break;
  162.     }
  163. }
  164.