1/*- 2 * Copyright (c) 1991, 1993, 1994 3 * The Regents of the University of California. 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 * --- 32 unchanged lines hidden (view full) --- 41 The Regents of the University of California. All rights reserved.\n"; 42#endif /* not lint */ 43 44#ifndef lint 45#if 0 46static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94"; 47#endif 48static const char rcsid[] = |
49 "$FreeBSD: head/bin/dd/dd.c 51208 1999-09-12 16:51:53Z green $"; |
50#endif /* not lint */ 51 52#include <sys/param.h> 53#include <sys/stat.h> 54#include <sys/conf.h> 55#include <sys/diskslice.h> 56#include <sys/filio.h> 57#include <sys/mtio.h> --- 17 unchanged lines hidden (view full) --- 75static void setup __P((void)); 76 77IO in, out; /* input/output state */ 78STAT st; /* statistics */ 79void (*cfunc) __P((void)); /* conversion function */ 80quad_t cpy_cnt; /* # of blocks to copy */ 81off_t pending = 0; /* pending seek if sparse */ 82u_int ddflags; /* conversion options */ |
83size_t cbsz; /* conversion block size */ |
84quad_t files_cnt = 1; /* # of files to copy */ |
85const u_char *ctab; /* conversion table */ |
86 87int 88main(argc, argv) 89 int argc; 90 char *argv[]; 91{ 92 (void)setlocale(LC_CTYPE, ""); 93 jcl(argv); --- 55 unchanged lines hidden (view full) --- 149 getfdtype(&out); 150 151 /* 152 * Allocate space for the input and output buffers. If not doing 153 * record oriented I/O, only need a single buffer. 154 */ 155 if (!(ddflags & (C_BLOCK|C_UNBLOCK))) { 156 if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) |
157 err(1, "input buffer"); |
158 out.db = in.db; |
159 } else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL || 160 (out.db = malloc(out.dbsz + cbsz)) == NULL) 161 err(1, "output buffer"); |
162 in.dbp = in.db; 163 out.dbp = out.db; 164 165 /* Position the input/output streams. */ 166 if (in.offset) 167 pos_in(); 168 if (out.offset) 169 pos_out(); --- 6 unchanged lines hidden (view full) --- 176 (void)ftruncate(out.fd, out.offset * out.dbsz); 177 178 /* 179 * If converting case at the same time as another conversion, build a 180 * table that does both at once. If just converting case, use the 181 * built-in tables. 182 */ 183 if (ddflags & (C_LCASE|C_UCASE)) { |
184 if (ddflags & (C_ASCII|C_EBCDIC)) { |
185 if (ddflags & C_LCASE) { 186 for (cnt = 0; cnt <= 0377; ++cnt) |
187 casetab[cnt] = tolower(ctab[cnt]); |
188 } else { 189 for (cnt = 0; cnt <= 0377; ++cnt) |
190 casetab[cnt] = toupper(ctab[cnt]); |
191 } |
192 } else { |
193 if (ddflags & C_LCASE) { 194 for (cnt = 0; cnt <= 0377; ++cnt) |
195 casetab[cnt] = tolower(cnt); |
196 } else { 197 for (cnt = 0; cnt <= 0377; ++cnt) |
198 casetab[cnt] = toupper(cnt); |
199 } 200 } |
201 ctab = casetab; |
202 } |
203 |
204 (void)gettimeofday(&tv, (struct timezone *)NULL); 205 st.start = tv.tv_sec + tv.tv_usec * 1e-6; 206} 207 208static void 209getfdtype(io) 210 IO *io; 211{ 212 struct stat sb; 213 int type; 214 |
215 if (fstat(io->fd, &sb) == -1) |
216 err(1, "%s", io->name); 217 if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) { 218 if (ioctl(io->fd, FIODTYPE, &type) == -1) { 219 warn("%s", io->name); 220 if (S_ISCHR(sb.st_mode)) 221 io->flags |= ISCHR; 222 } else { 223 if (type & D_TAPE) --- 12 unchanged lines hidden (view full) --- 236{ 237 ssize_t n; 238 239 for (;;) { 240 if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt) 241 return; 242 243 /* |
244 * Zero the buffer first if sync; if doing block operations, |
245 * use spaces. 246 */ 247 if (ddflags & C_SYNC) { 248 if (ddflags & (C_BLOCK|C_UNBLOCK)) 249 memset(in.dbp, ' ', in.dbsz); 250 else 251 memset(in.dbp, 0, in.dbsz); 252 } --- 69 unchanged lines hidden (view full) --- 322 } 323 324 in.dbp += in.dbrcnt; 325 (*cfunc)(); 326 } 327} 328 329/* |
330 * Clea nup any remaining I/O and flush output. If necessary, the output file |
331 * is truncated. 332 */ 333static void 334dd_close() 335{ 336 if (cfunc == def) 337 def_close(); 338 else if (cfunc == block) --- 10 unchanged lines hidden (view full) --- 349 if (out.dbcnt || pending) 350 dd_out(1); 351} 352 353void 354dd_out(force) 355 int force; 356{ |
357 u_char *outp; |
358 size_t cnt, i, n; 359 ssize_t nw; 360 static int warned; 361 int sparse; |
362 363 /* 364 * Write one or more blocks out. The common case is writing a full 365 * output block in a single write; increment the full block stats. 366 * Otherwise, we're into partial block writes. If a partial write, 367 * and it's a character device, just warn. If a tape device, quit. 368 * 369 * The partial writes represent two cases. 1: Where the input block --- 67 unchanged lines hidden (view full) --- 437 errx(1, "%s: short write on tape device", out.name); 438 } 439 if ((out.dbcnt -= n) < out.dbsz) 440 break; 441 } 442 443 /* Reassemble the output block. */ 444 if (out.dbcnt) |
445 (void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt); |
446 out.dbp = out.db + out.dbcnt; 447} |