coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

coreutils/src/cp.c (113 lines, 3.4 KiB) -rw-r--r-- file download

14d235f Jamozed 2021-04-29 17:38:15
0
// cp.c, version 0.0.2
d57b240 Jamozed 2022-02-28 12:42:27
1
// OMKOV coreutils implementation of POSIX cp
d920c1b Jamozed 2021-03-07 23:52:19
2
// Copyright (C) 2021, Jakob Wakeling
e2140ec Jamozed 2022-03-06 15:27:45
3
// MIT Licence
d920c1b Jamozed 2021-03-07 23:52:19
4
b181413 Jamozed 2022-02-05 22:32:00
5
#include "util/error.h"
b181413 Jamozed 2022-02-05 22:32:00
6
#include "util/optget.h"
d920c1b Jamozed 2021-03-07 23:52:19
7
d920c1b Jamozed 2021-03-07 23:52:19
8
#include <sys/stat.h>
d920c1b Jamozed 2021-03-07 23:52:19
9
d920c1b Jamozed 2021-03-07 23:52:19
10
#include <stdbool.h>
d920c1b Jamozed 2021-03-07 23:52:19
11
#include <stdint.h>
d920c1b Jamozed 2021-03-07 23:52:19
12
#include <stdio.h>
d920c1b Jamozed 2021-03-07 23:52:19
13
14d235f Jamozed 2021-04-29 17:38:15
14
#define VERSION "0.0.2"
d920c1b Jamozed 2021-03-07 23:52:19
15
d920c1b Jamozed 2021-03-07 23:52:19
16
static struct lop lops[] = {
d920c1b Jamozed 2021-03-07 23:52:19
17
	{ "help",    ARG_NUL, 256 },
d920c1b Jamozed 2021-03-07 23:52:19
18
	{ "version", ARG_NUL, 257 },
d920c1b Jamozed 2021-03-07 23:52:19
19
	{ NULL, 0, 0 }
d920c1b Jamozed 2021-03-07 23:52:19
20
};
d920c1b Jamozed 2021-03-07 23:52:19
21
d920c1b Jamozed 2021-03-07 23:52:19
22
static bool fflag, Hflag, iflag, Lflag, Pflag, pflag, Rflag;
d920c1b Jamozed 2021-03-07 23:52:19
23
14d235f Jamozed 2021-04-29 17:38:15
24
static inline void cp(const char *dst, char *const *src, size_t n);
14d235f Jamozed 2021-04-29 17:38:15
25
static inline void fcopy(const char *dst, const char *src);
d920c1b Jamozed 2021-03-07 23:52:19
26
static inline bool fsame(FILE *f1, FILE *f2);
d920c1b Jamozed 2021-03-07 23:52:19
27
d920c1b Jamozed 2021-03-07 23:52:19
28
static void hlp(void);
d920c1b Jamozed 2021-03-07 23:52:19
29
static void ver(void);
d920c1b Jamozed 2021-03-07 23:52:19
30
d920c1b Jamozed 2021-03-07 23:52:19
31
int main(int ac, char *av[]) { A0 = av[0];
d920c1b Jamozed 2021-03-07 23:52:19
32
	struct opt opt = OPTGET_INIT; opt.str = "fHiLPpR"; opt.lops = lops;
d920c1b Jamozed 2021-03-07 23:52:19
33
	for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) {
d920c1b Jamozed 2021-03-07 23:52:19
34
	case 'f': { fflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
35
	case 'H': { Hflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
36
	case 'i': { iflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
37
	case 'L': { Lflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
38
	case 'P': { Pflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
39
	case 'p': { pflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
40
	case 'R': { Rflag = true; break; }
d920c1b Jamozed 2021-03-07 23:52:19
41
	case 256: { hlp(); return 0; }
d920c1b Jamozed 2021-03-07 23:52:19
42
	case 257: { ver(); return 0; }
d920c1b Jamozed 2021-03-07 23:52:19
43
	default: { return 1; }
d920c1b Jamozed 2021-03-07 23:52:19
44
	}
d920c1b Jamozed 2021-03-07 23:52:19
45
	
d920c1b Jamozed 2021-03-07 23:52:19
46
	if (opt.ind == ac) { error(1, "missing source operand"); }
d920c1b Jamozed 2021-03-07 23:52:19
47
	else if (opt.ind == ac - 1) { error(1, "missing destination operand"); }
14d235f Jamozed 2021-04-29 17:38:15
48
	else { cp(av[ac - 1], &av[opt.ind], ac - opt.ind - 1); }
d920c1b Jamozed 2021-03-07 23:52:19
49
	
d920c1b Jamozed 2021-03-07 23:52:19
50
	return warned;
d920c1b Jamozed 2021-03-07 23:52:19
51
}
d920c1b Jamozed 2021-03-07 23:52:19
52
14d235f Jamozed 2021-04-29 17:38:15
53
/* Copy one or more files to a specified destination */
14d235f Jamozed 2021-04-29 17:38:15
54
static inline void cp(const char *dst, char *const *src, size_t n) {
14d235f Jamozed 2021-04-29 17:38:15
55
	return fcopy(dst, *src);
14d235f Jamozed 2021-04-29 17:38:15
56
}
14d235f Jamozed 2021-04-29 17:38:15
57
d920c1b Jamozed 2021-03-07 23:52:19
58
/* Copy a file to a specified destination */
14d235f Jamozed 2021-04-29 17:38:15
59
static inline void fcopy(const char *dst, const char *src) {
d920c1b Jamozed 2021-03-07 23:52:19
60
	uint8_t b[BUFSIZ * 16]; FILE *fi = NULL, *fo = NULL; struct stat st;
d920c1b Jamozed 2021-03-07 23:52:19
61
	
d920c1b Jamozed 2021-03-07 23:52:19
62
	if (!(fi = fopen(src, "rb"))) { warn("%s: %s", src, serr()); goto end; }
d920c1b Jamozed 2021-03-07 23:52:19
63
	if (!(fo = fopen(dst, "wb"))) { warn("%s: %s", dst, serr()); goto end; }
d920c1b Jamozed 2021-03-07 23:52:19
64
	
d920c1b Jamozed 2021-03-07 23:52:19
65
	if (fsame(fi, fo)) { warn("%s, %s: same file", src, dst); goto end; }
d920c1b Jamozed 2021-03-07 23:52:19
66
	
d920c1b Jamozed 2021-03-07 23:52:19
67
	for (register size_t c; (c = fread(b, 1, sizeof (b), fi));) {
d920c1b Jamozed 2021-03-07 23:52:19
68
		if (fwrite(b, 1, c, fo) != c) { warn("%s: %s", dst, serr()); goto end; }
d920c1b Jamozed 2021-03-07 23:52:19
69
	}
d920c1b Jamozed 2021-03-07 23:52:19
70
	
d920c1b Jamozed 2021-03-07 23:52:19
71
	// Copy permissions from src to destination
d920c1b Jamozed 2021-03-07 23:52:19
72
	if (stat(src, &st)) { warn("%s: %s", src, serr()); goto end; }
d920c1b Jamozed 2021-03-07 23:52:19
73
	if (chmod(dst, st.st_mode)) { warn("%s: %s", dst, serr()); goto end; }
d920c1b Jamozed 2021-03-07 23:52:19
74
	
d920c1b Jamozed 2021-03-07 23:52:19
75
end:;
d920c1b Jamozed 2021-03-07 23:52:19
76
	if (fi && fclose(fi)) { warn("%s: %s", src, serr()); }
d920c1b Jamozed 2021-03-07 23:52:19
77
	if (fo && fclose(fo)) { warn("%s: %s", dst, serr()); }
d920c1b Jamozed 2021-03-07 23:52:19
78
	return;
d920c1b Jamozed 2021-03-07 23:52:19
79
}
d920c1b Jamozed 2021-03-07 23:52:19
80
d920c1b Jamozed 2021-03-07 23:52:19
81
/* Check if two FILEs point to the same file */
d920c1b Jamozed 2021-03-07 23:52:19
82
static inline bool fsame(FILE *f1, FILE *f2) {
d920c1b Jamozed 2021-03-07 23:52:19
83
	struct stat s1, s2; fstat(fileno(f1), &s1); fstat(fileno(f2), &s2);
d920c1b Jamozed 2021-03-07 23:52:19
84
	return (s1.st_dev == s2.st_dev) && (s1.st_ino == s2.st_ino);
d920c1b Jamozed 2021-03-07 23:52:19
85
}
d920c1b Jamozed 2021-03-07 23:52:19
86
d920c1b Jamozed 2021-03-07 23:52:19
87
/* Print help information */
d920c1b Jamozed 2021-03-07 23:52:19
88
static void hlp(void) {
d920c1b Jamozed 2021-03-07 23:52:19
89
	puts("cp - Copy files");
d920c1b Jamozed 2021-03-07 23:52:19
90
	puts("\nUsage:");
d920c1b Jamozed 2021-03-07 23:52:19
91
	puts("  cp [-Pfip] source destination");
d920c1b Jamozed 2021-03-07 23:52:19
92
	puts("  cp [-Pfip] source... destination");
d920c1b Jamozed 2021-03-07 23:52:19
93
	puts("  cp -R [-H|-L|-P] [-fip] source... destination");
d920c1b Jamozed 2021-03-07 23:52:19
94
	puts("\nOptions:");
d920c1b Jamozed 2021-03-07 23:52:19
95
	puts("  -f         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
96
	puts("  -H         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
97
	puts("  -i         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
98
	puts("  -L         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
99
	puts("  -P         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
100
	puts("  -p         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
101
	puts("  -R         UNIMPLEMENTED");
d920c1b Jamozed 2021-03-07 23:52:19
102
	puts("  --help     Display help information");
d920c1b Jamozed 2021-03-07 23:52:19
103
	puts("  --version  Display version information");
d920c1b Jamozed 2021-03-07 23:52:19
104
}
d920c1b Jamozed 2021-03-07 23:52:19
105
d920c1b Jamozed 2021-03-07 23:52:19
106
/* Print version information */
d920c1b Jamozed 2021-03-07 23:52:19
107
static void ver(void) {
d920c1b Jamozed 2021-03-07 23:52:19
108
	puts("OMKOV coreutils cp, version " VERSION);
d920c1b Jamozed 2021-03-07 23:52:19
109
	puts("Copyright (C) 2021, Jakob Wakeling");
e2140ec Jamozed 2022-03-06 15:27:45
110
	puts("MIT Licence (https://opensource.org/licenses/MIT)");
d920c1b Jamozed 2021-03-07 23:52:19
111
}
112