1: /*
   2:  * Copyright (c) 1983 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #ifndef lint
   8: char copyright[] =
   9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: #endif not lint
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)cp.c	4.13 (Berkeley) 10/11/85";
  15: #endif not lint
  16: 
  17: /*
  18:  * cp
  19:  */
  20: #include <stdio.h>
  21: #include <sys/param.h>
  22: #include <sys/stat.h>
  23: #include <sys/dir.h>
  24: #include <sys/time.h>
  25: 
  26: int iflag;
  27: int rflag;
  28: int pflag;
  29: char    *rindex();
  30: 
  31: main(argc, argv)
  32:     int argc;
  33:     char **argv;
  34: {
  35:     struct stat stb;
  36:     int rc, i;
  37: 
  38:     argc--, argv++;
  39:     while (argc > 0 && **argv == '-') {
  40:         (*argv)++;
  41:         while (**argv) switch (*(*argv)++) {
  42: 
  43:         case 'i':
  44:             iflag++; break;
  45: 
  46:         case 'R':
  47:         case 'r':
  48:             rflag++; break;
  49: 
  50:         case 'p':   /* preserve mtimes, atimes, and modes */
  51:             pflag++;
  52:             (void) umask(0);
  53:             break;
  54: 
  55:         default:
  56:             goto usage;
  57:         }
  58:         argc--; argv++;
  59:     }
  60:     if (argc < 2)
  61:         goto usage;
  62:     if (argc > 2) {
  63:         if (stat(argv[argc-1], &stb) < 0)
  64:             goto usage;
  65:         if ((stb.st_mode&S_IFMT) != S_IFDIR)
  66:             goto usage;
  67:     }
  68:     rc = 0;
  69:     for (i = 0; i < argc-1; i++)
  70:         rc |= copy(argv[i], argv[argc-1]);
  71:     exit(rc);
  72: usage:
  73:     fprintf(stderr,
  74:         "Usage: cp [-ip] f1 f2; or: cp [-irp] f1 ... fn d2\n");
  75:     exit(1);
  76: }
  77: 
  78: copy(from, to)
  79:     char *from, *to;
  80: {
  81:     int fold, fnew, n, exists;
  82:     char *last, destname[MAXPATHLEN + 1], buf[MAXBSIZE];
  83:     struct stat stfrom, stto;
  84: 
  85:     fold = open(from, 0);
  86:     if (fold < 0) {
  87:         Perror(from);
  88:         return (1);
  89:     }
  90:     if (fstat(fold, &stfrom) < 0) {
  91:         Perror(from);
  92:         (void) close(fold);
  93:         return (1);
  94:     }
  95:     if (stat(to, &stto) >= 0 &&
  96:        (stto.st_mode&S_IFMT) == S_IFDIR) {
  97:         last = rindex(from, '/');
  98:         if (last) last++; else last = from;
  99:         if (strlen(to) + strlen(last) >= sizeof destname - 1) {
 100:             fprintf(stderr, "cp: %s/%s: Name too long", to, last);
 101:             (void) close(fold);
 102:             return(1);
 103:         }
 104:         (void) sprintf(destname, "%s/%s", to, last);
 105:         to = destname;
 106:     }
 107:     if (rflag && (stfrom.st_mode&S_IFMT) == S_IFDIR) {
 108:         int fixmode = 0;    /* cleanup mode after rcopy */
 109: 
 110:         (void) close(fold);
 111:         if (stat(to, &stto) < 0) {
 112:             if (mkdir(to, (stfrom.st_mode & 07777) | 0700) < 0) {
 113:                 Perror(to);
 114:                 return (1);
 115:             }
 116:             fixmode = 1;
 117:         } else if ((stto.st_mode&S_IFMT) != S_IFDIR) {
 118:             fprintf(stderr, "cp: %s: Not a directory.\n", to);
 119:             return (1);
 120:         } else if (pflag)
 121:             fixmode = 1;
 122:         n = rcopy(from, to);
 123:         if (fixmode)
 124:             (void) chmod(to, stfrom.st_mode & 07777);
 125:         return (n);
 126:     }
 127: 
 128:     if ((stfrom.st_mode&S_IFMT) == S_IFDIR)
 129:         fprintf(stderr,
 130:             "cp: %s: Is a directory (copying as plain file).\n",
 131:                 from);
 132: 
 133:     exists = stat(to, &stto) == 0;
 134:     if (exists) {
 135:         if (stfrom.st_dev == stto.st_dev &&
 136:            stfrom.st_ino == stto.st_ino) {
 137:             fprintf(stderr,
 138:                 "cp: %s and %s are identical (not copied).\n",
 139:                     from, to);
 140:             (void) close(fold);
 141:             return (1);
 142:         }
 143:         if (iflag && isatty(fileno(stdin))) {
 144:             int i, c;
 145: 
 146:             fprintf (stderr, "overwrite %s? ", to);
 147:             i = c = getchar();
 148:             while (c != '\n' && c != EOF)
 149:                 c = getchar();
 150:             if (i != 'y') {
 151:                 (void) close(fold);
 152:                 return(1);
 153:             }
 154:         }
 155:     }
 156:     fnew = creat(to, stfrom.st_mode & 07777);
 157:     if (fnew < 0) {
 158:         Perror(to);
 159:         (void) close(fold); return(1);
 160:     }
 161:     if (exists && pflag)
 162:         (void) fchmod(fnew, stfrom.st_mode & 07777);
 163: 
 164:     for (;;) {
 165:         n = read(fold, buf, sizeof buf);
 166:         if (n == 0)
 167:             break;
 168:         if (n < 0) {
 169:             Perror(from);
 170:             (void) close(fold); (void) close(fnew); return (1);
 171:         }
 172:         if (write(fnew, buf, n) != n) {
 173:             Perror(to);
 174:             (void) close(fold); (void) close(fnew); return (1);
 175:         }
 176:     }
 177:     (void) close(fold); (void) close(fnew);
 178:     if (pflag)
 179:         return (setimes(to, &stfrom));
 180:     return (0);
 181: }
 182: 
 183: rcopy(from, to)
 184:     char *from, *to;
 185: {
 186:     DIR *fold = opendir(from);
 187:     struct direct *dp;
 188:     struct stat statb;
 189:     int errs = 0;
 190:     char fromname[MAXPATHLEN + 1];
 191: 
 192:     if (fold == 0 || (pflag && fstat(fold->dd_fd, &statb) < 0)) {
 193:         Perror(from);
 194:         return (1);
 195:     }
 196:     for (;;) {
 197:         dp = readdir(fold);
 198:         if (dp == 0) {
 199:             closedir(fold);
 200:             if (pflag)
 201:                 return (setimes(to, &statb) + errs);
 202:             return (errs);
 203:         }
 204:         if (dp->d_ino == 0)
 205:             continue;
 206:         if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
 207:             continue;
 208:         if (strlen(from)+1+strlen(dp->d_name) >= sizeof fromname - 1) {
 209:             fprintf(stderr, "cp: %s/%s: Name too long.\n",
 210:                 from, dp->d_name);
 211:             errs++;
 212:             continue;
 213:         }
 214:         (void) sprintf(fromname, "%s/%s", from, dp->d_name);
 215:         errs += copy(fromname, to);
 216:     }
 217: }
 218: 
 219: int
 220: setimes(path, statp)
 221:     char *path;
 222:     struct stat *statp;
 223: {
 224:     struct timeval tv[2];
 225: 
 226:     tv[0].tv_sec = statp->st_atime;
 227:     tv[1].tv_sec = statp->st_mtime;
 228:     tv[0].tv_usec = tv[1].tv_usec = 0;
 229:     if (utimes(path, tv) < 0) {
 230:         Perror(path);
 231:         return (1);
 232:     }
 233:     return (0);
 234: }
 235: 
 236: Perror(s)
 237:     char *s;
 238: {
 239: 
 240:     fprintf(stderr, "cp: ");
 241:     perror(s);
 242: }

Defined functions

Perror defined in line 236; used 8 times
copy defined in line 78; used 2 times
main defined in line 31; never used
rcopy defined in line 183; used 1 times
setimes defined in line 219; used 2 times

Defined variables

copyright defined in line 8; never used
iflag defined in line 26; used 2 times
pflag defined in line 28; used 6 times
rflag defined in line 27; used 2 times
sccsid defined in line 14; never used
Last modified: 1987-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5316
Valid CSS Valid XHTML 1.0 Strict