# 2.11BSD#431 - /usr/src/bin/cp.c

##### Functions

    Perror            X
    copy              X
    main              X
    rcopy             X
    setimes           X

##### Variables

    copyright         X
    iflag             X
    pflag             X
    rflag             X

       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

- in line 87-91(2), 113, 158, 169-173(2), 193, 230

copy defined in line 78; used 2 times

- in line 70, 215

main defined in line 31; never used
rcopy defined in line 183; used 1 times

- in line 122

setimes defined in line 219; used 2 times

- in line 179, 201

#### Defined variables

copyright defined in line 8; never used
iflag defined in line 26; used 2 times

- in line 44, 143

pflag defined in line 28; used 6 times

- in line 51, 120, 161, 178, 192, 200

rflag defined in line 27; used 2 times

- in line 48, 107

sccsid defined in line 14; never used

Last modified: 1987-02-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2392 |