Annotation of prex/usr/bin/cp/cp.c, Revision 1.1
1.1 ! nbrk 1: /*
! 2: * Copyright (c) 1988, 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: * David Hitz of Auspex Systems Inc.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: * 3. Neither the name of the University nor the names of its contributors
! 17: * may be used to endorse or promote products derived from this software
! 18: * without specific prior written permission.
! 19: *
! 20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 30: * SUCH DAMAGE.
! 31: */
! 32:
! 33: #include <sys/stat.h>
! 34: #include <sys/fcntl.h>
! 35:
! 36: #include <unistd.h>
! 37: #include <err.h>
! 38: #include <string.h>
! 39: #include <stdlib.h>
! 40: #include <errno.h>
! 41: #include <limits.h>
! 42: #include <stdio.h>
! 43:
! 44: #ifdef CMDBOX
! 45: #define main(argc, argv) cp_main(argc, argv)
! 46: #endif
! 47:
! 48: static void usage(void);
! 49: static int copy(char *from, char *to, int dirflag);
! 50:
! 51:
! 52: static char iobuf[BUFSIZ];
! 53:
! 54: int
! 55: main(int argc, char *argv[])
! 56: {
! 57: int r, ch, checkch, i, iflag = 0;
! 58: char *target;
! 59: struct stat to_stat, tmp_stat;
! 60:
! 61: while ((ch = getopt(argc, argv, "i")) != -1)
! 62: switch(ch) {
! 63: case 'i':
! 64: iflag = isatty(fileno(stdin));
! 65: break;
! 66: case '?':
! 67: default:
! 68: usage();
! 69: }
! 70: argc -= optind;
! 71: argv += optind;
! 72:
! 73: if (argc < 2)
! 74: usage();
! 75:
! 76: target = argv[--argc];
! 77:
! 78: r = stat(target, &to_stat);
! 79: if (r == -1 && errno != ENOENT)
! 80: err(1, "%s", target);
! 81: if (r == -1 || !S_ISDIR(to_stat.st_mode)) {
! 82: /*
! 83: * File to file
! 84: */
! 85: if (argc > 1) {
! 86: usage();
! 87: exit(1);
! 88: }
! 89: stat(argv[0], &tmp_stat);
! 90: if (!S_ISREG(tmp_stat.st_mode))
! 91: usage();
! 92:
! 93: /* interactive mode */
! 94: if (r != -1 && iflag) {
! 95: (void)fprintf(stderr, "overwrite %s? ", target);
! 96: checkch = ch = getchar();
! 97: while (ch != '\n' && ch != EOF)
! 98: ch = getchar();
! 99: if (checkch != 'y')
! 100: exit(0);
! 101: }
! 102: r = copy(argv[0], target, 0);
! 103: } else {
! 104: /*
! 105: * File(s) to directory
! 106: */
! 107: r = 0;
! 108: for (i = 0; i < argc; i++)
! 109: r = copy(argv[i], target, 1);
! 110: }
! 111: exit(r);
! 112: }
! 113:
! 114: static void
! 115: usage(void)
! 116: {
! 117: fprintf(stderr, "usage: cp [-i] src target\n"
! 118: " cp [-i] src1 ... srcN directory\n");
! 119: exit(1);
! 120: /* NOTREACHED */
! 121: }
! 122:
! 123: static int
! 124: copy(char *from, char *to, int dirflag)
! 125: {
! 126: char path[PATH_MAX];
! 127: int fold, fnew, n, mode;
! 128: struct stat stbuf;
! 129: char *p;
! 130:
! 131: if (dirflag) {
! 132: p = strrchr(from, '/');
! 133: p = p ? p + 1 : from;
! 134: strcpy(path, to);
! 135: if (strcmp(to, "/"))
! 136: strcat(path, "/");
! 137: strcat(path, p);
! 138: to = path;
! 139: }
! 140:
! 141: if ((fold = open(from, 0)) == -1) {
! 142: warn("%s", from);
! 143: return 1;
! 144: }
! 145: fstat(fold, &stbuf);
! 146: mode = stbuf.st_mode;
! 147:
! 148: if ((fnew = creat(to, mode)) == -1) {
! 149: warn("%s", to);
! 150: close(fold);
! 151: return 1;
! 152: }
! 153: while ((n = read(fold, iobuf, BUFSIZ)) > 0) {
! 154: if (write(fnew, iobuf, n) != n) {
! 155: warn("%s", to);
! 156: close(fold);
! 157: close(fnew);
! 158: return 1;
! 159: }
! 160: }
! 161: close(fold);
! 162: close(fnew);
! 163: return 0;
! 164: }
CVSweb