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
|
|