Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:19

0001 /*-
0002  * Copyright (c) 1991, 1993, 1994
0003  *  The Regents of the University of California.  All rights reserved.
0004  *
0005  * This code is derived from software contributed to Berkeley by
0006  * Keith Muller of the University of California, San Diego and Lance
0007  * Visser of Convex Computer Corporation.
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  * 4. Neither the name of the University nor the names of its contributors
0018  *    may be used to endorse or promote products derived from this software
0019  *    without specific prior written permission.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
0022  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
0025  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0026  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
0027  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0028  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
0029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
0030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
0031  * SUCH DAMAGE.
0032  */
0033 
0034 #ifdef HAVE_CONFIG_H
0035 #include "config.h"
0036 #endif
0037 
0038 #ifndef lint
0039 #if 0
0040 static char sccsid[] = "@(#)position.c  8.3 (Berkeley) 4/2/94";
0041 #include <sys/cdefs.h>
0042 __FBSDID("$FreeBSD: src/bin/dd/position.c,v 1.23 2004/04/06 20:06:46 markm Exp $");
0043 #endif
0044 #endif /* not lint */
0045 
0046 #include <sys/types.h>
0047 #if RTEMS_REMOVED
0048 #include <sys/mtio.h>
0049 #endif
0050 
0051 #include "err.h"
0052 #include <errno.h>
0053 #include <inttypes.h>
0054 #include <unistd.h>
0055 
0056 #include "dd.h"
0057 #include "extern-dd.h"
0058 
0059 /*
0060  * Position input/output data streams before starting the copy.  Device type
0061  * dependent.  Seekable devices use lseek, and the rest position by reading.
0062  * Seeking past the end of file can cause null blocks to be written to the
0063  * output.
0064  */
0065 void
0066 pos_in(rtems_shell_dd_globals* globals)
0067 {
0068     off_t cnt;
0069     int warned;
0070     ssize_t nr;
0071     size_t bcnt;
0072 
0073     /* If known to be seekable, try to seek on it. */
0074     if (in.flags & ISSEEK) {
0075         errno = 0;
0076         if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 &&
0077             errno != 0)
0078             err(exit_jump, 1, "%s", in.name);
0079         return;
0080     }
0081 
0082     /* Don't try to read a really weird amount (like negative). */
0083     if (in.offset < 0)
0084         errx(exit_jump, 1, "%s: illegal offset", "iseek/skip");
0085 
0086     /*
0087      * Read the data.  If a pipe, read until satisfy the number of bytes
0088      * being skipped.  No differentiation for reading complete and partial
0089      * blocks for other devices.
0090      */
0091     for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
0092         if ((nr = read(in.fd, in.db, bcnt)) > 0) {
0093             if (in.flags & ISPIPE) {
0094                 if (!(bcnt -= nr)) {
0095                     bcnt = in.dbsz;
0096                     --cnt;
0097                 }
0098             } else
0099                 --cnt;
0100             continue;
0101         }
0102 
0103         if (nr == 0) {
0104             if (files_cnt > 1) {
0105                 --files_cnt;
0106                 continue;
0107             }
0108             errx(exit_jump, 1, "skip reached end of input");
0109         }
0110 
0111         /*
0112          * Input error -- either EOF with no more files, or I/O error.
0113          * If noerror not set die.  POSIX requires that the warning
0114          * message be followed by an I/O display.
0115          */
0116         if (ddflags & C_NOERROR) {
0117             if (!warned) {
0118                 warn("%s", in.name);
0119                 warned = 1;
0120                 summary(globals);
0121             }
0122             continue;
0123         }
0124         err(exit_jump, 1, "%s", in.name);
0125     }
0126 }
0127 
0128 void
0129 pos_out(rtems_shell_dd_globals* globals)
0130 {
0131 #if RTEMS_REMOVED
0132     struct mtop t_op;
0133     off_t cnt;
0134     ssize_t n;
0135 #endif
0136 
0137     /*
0138      * If not a tape, try seeking on the file.  Seeking on a pipe is
0139      * going to fail, but don't protect the user -- they shouldn't
0140      * have specified the seek operand.
0141      */
0142     if (out.flags & (ISSEEK | ISPIPE)) {
0143         errno = 0;
0144         if (lseek(out.fd, out.offset * out.dbsz, SEEK_CUR) == -1 &&
0145             errno != 0)
0146             err(exit_jump, 1, "%s", out.name);
0147         return;
0148     }
0149 
0150     /* Don't try to read a really weird amount (like negative). */
0151     if (out.offset < 0)
0152         errx(exit_jump, 1, "%s: illegal offset", "oseek/seek");
0153 
0154 #if RTEMS_REMOVED
0155     /* If no read access, try using mtio. */
0156     if (out.flags & NOREAD) {
0157         t_op.mt_op = MTFSR;
0158         t_op.mt_count = out.offset;
0159 
0160         if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
0161             err(1, "%s", out.name);
0162         return;
0163     }
0164 
0165     /* Read it. */
0166     for (cnt = 0; cnt < out.offset; ++cnt) {
0167         if ((n = read(out.fd, out.db, out.dbsz)) > 0)
0168             continue;
0169 
0170         if (n == -1)
0171             err(1, "%s", out.name);
0172 
0173         /*
0174          * If reach EOF, fill with NUL characters; first, back up over
0175          * the EOF mark.  Note, cnt has not yet been incremented, so
0176          * the EOF read does not count as a seek'd block.
0177          */
0178         t_op.mt_op = MTBSR;
0179         t_op.mt_count = 1;
0180         if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
0181             err(1, "%s", out.name);
0182 
0183         while (cnt++ < out.offset) {
0184             n = write(out.fd, out.db, out.dbsz);
0185             if (n == -1)
0186                 err(1, "%s", out.name);
0187             if ((size_t)n != out.dbsz)
0188                 errx(1, "%s: write failure", out.name);
0189         }
0190         break;
0191     }
0192 #endif
0193 }