xref: /original-bsd/bin/cp/cp.c (revision cc77da92)
1 static char *sccsid = "@(#)cp.c	4.1 (Berkeley) 10/01/80";
2 /*
3  * cp oldfile newfile
4  */
5 
6 #define	BSIZE	1024
7 #include <stdio.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 struct	stat	stbuf1, stbuf2;
11 char	iobuf[BSIZE];
12 int	iflag = 0;	/* interactive flag. If this flag is set,
13 			 * the user is queried before files are
14 			 * destroyed by cp.
15 			 */
16 
17 main(argc, argv)
18 char *argv[];
19 {
20 	register i, r;
21 
22 	/* get the flag(s) */
23 
24 	if (argc < 2)
25 		goto usage;
26 	if (*argv[1] == '-') {
27 		argc--;
28 		while (*++argv[1] != '\0')
29 			switch (*argv[1]) {
30 
31 			/* interactive mode */
32 			case 'i':
33 				iflag++;
34 				break;
35 
36 			/* don't live with bad options */
37 			default:
38 				goto usage;
39 			}
40 		argv++;
41 	}
42 	if (argc < 3)
43 		goto usage;
44 	if (argc > 3) {
45 		if (stat(argv[argc-1], &stbuf2) < 0)
46 			goto usage;
47 		if ((stbuf2.st_mode&S_IFMT) != S_IFDIR)
48 			goto usage;
49 	}
50 	r = 0;
51 	for(i=1; i<argc-1;i++)
52 		r |= copy(argv[i], argv[argc-1]);
53 	exit(r);
54 usage:
55 	fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
56 	exit(1);
57 }
58 
59 copy(from, to)
60 char *from, *to;
61 {
62 	int fold, fnew, n;
63 	register char *p1, *p2, *bp;
64 	int mode;
65 	char c,i;
66 	if ((fold = open(from, 0)) < 0) {
67 		fprintf(stderr, "cp: cannot open %s\n", from);
68 		return(1);
69 	}
70 	fstat(fold, &stbuf1);
71 	mode = stbuf1.st_mode;
72 	/* is target a directory? */
73 	if (stat(to, &stbuf2) >=0 &&
74 	   (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
75 		p1 = from;
76 		p2 = to;
77 		bp = iobuf;
78 		while(*bp++ = *p2++)
79 			;
80 		bp[-1] = '/';
81 		p2 = bp;
82 		while(*bp = *p1++)
83 			if (*bp++ == '/')
84 				bp = p2;
85 		to = iobuf;
86 	}
87 	if (stat(to, &stbuf2) >= 0) {
88 		if (stbuf1.st_dev == stbuf2.st_dev &&
89 		   stbuf1.st_ino == stbuf2.st_ino) {
90 			fprintf(stderr, "cp: cannot copy file to itself.\n");
91 			return(1);
92 		} else if (iflag) {
93 			fprintf (stderr, "overwrite %s? ", to);
94 			i = c = getchar();
95 			while (c != '\n' && c != EOF)
96 				c = getchar();
97 			if (i != 'y')
98 				return(1);
99 		}
100 	}
101 	if ((fnew = creat(to, mode)) < 0) {
102 		fprintf(stderr, "cp: cannot create %s\n", to);
103 		close(fold);
104 		return(1);
105 	}
106 	while(n = read(fold,  iobuf,  BSIZE)) {
107 		if (n < 0) {
108 			perror("cp: read");
109 			close(fold);
110 			close(fnew);
111 			return(1);
112 		} else
113 			if (write(fnew, iobuf, n) != n) {
114 				perror("cp: write");
115 				close(fold);
116 				close(fnew);
117 				return(1);
118 			}
119 	}
120 	close(fold);
121 	close(fnew);
122 	return(0);
123 }
124