-
Notifications
You must be signed in to change notification settings - Fork 6
/
2020-SE-01.c
125 lines (96 loc) · 2.77 KB
/
2020-SE-01.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <unistd.h>
#include <fcntl.h>
#include <err.h>
#include <sys/stat.h>
#include <stdint.h>
int fds[4];
int elSize[5] = {4, 1, 2, 8, 16};
struct Header {
uint32_t unused;
uint16_t len;
uint16_t unused2;
uint64_t unused3;
};
struct Header h;
struct Pair {
uint16_t offset, len;
};
struct Pair p[4];
int openFile(char* file, int index);
int openFile(char* file, int index) {
int fd;
if((fd = open(file, O_RDONLY)) == -1)
err(2, "ERROR: opening file for read: %s", file);
if(read(fd, &h, sizeof(h)) != sizeof(h))
err(5, "ERROR: reading header from file: %s", file);
struct stat st;
if(stat(file, &st) == -1)
err(3, "ERROR: running stat on file: %s", file);
if((st.st_size - 16) % elSize[index] != 0)
errx(4, "ERROR: invalid file structure");
if((st.st_size - 16) / elSize[index] != h.len)
errx(6, "ERROR: invalid element count in file: %s", file);
return fd;
}
int createFile(char* file);
int createFile(char* file) {
int fd;
if((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
err(7, "ERROR: creating file for write: %s", file);
if(write(fd, &h, sizeof(h)) != sizeof(h))
err(8, "ERROR: writing initial header in file: %s", file);
return fd;
}
void myLseek(int fd, int pos, int elementSize);
void myLseek(int fd, int pos, int elementSize) {
if(lseek(fd, 16 + (pos*elementSize), SEEK_SET) == -1)
err(9, "ERROR: running lseek() in file");
}
int myRead(int fd, uint64_t* buf, int size);
int myRead(int fd, uint64_t* buf, int size) {
int bytes = 0;
if((bytes = read(fd, buf, size)) == -1)
err(11, "ERROR: reading from file. size: %d", size);
return bytes;
}
int myWrite(int fd, uint64_t* buf, int size);
int myWrite(int fd, uint64_t* buf, int size) {
int bytes = 0;
if((bytes = write(fd, buf, size)) != size)
err(12, "ERROR: writin %d bytes to file", size);
return bytes;
}
int main(int argc, char** argv) {
if(argc != 7)
errx(1, "ERROR: params count. 6 expected");
int fd1 = openFile(argv[1], 4);
fds[0] = openFile(argv[2], 0);
fds[1] = openFile(argv[3], 1);
fds[2] = openFile(argv[4], 2);
fds[3] = openFile(argv[5], 3);
int fd2 = createFile(argv[6]);
struct Header newH = { 0, 0, 0, 0 };
int bytes = 0;
while((bytes = read(fd1, &p, elSize[4])) > 0) {
for(int i = 0; i < 4; ++i) {
myLseek(fds[i], p[i].offset, elSize[i]);
uint64_t buf;
for(uint16_t j = 0; j < p[i].len; ++j) {
myRead(fds[i], &buf, elSize[i]);
myWrite(fd2, &buf, elSize[i]);
}
newH.len += p[i].len;
}
}
if(bytes == -1)
err(10, "ERROR: reading complects from file1");
if(lseek(fd2, 0, SEEK_SET) == -1)
err(12, "ERROR: reseting lseek on file6");
if(write(fd2, &newH, sizeof(newH)) != sizeof(newH))
err(13, "ERROR: adding final header to file6");
close(fd1);
close(fd2);
for(int i = 0; i < 4; ++i)
close(fds[i]);
return 0;
}