header.c
unknown
plain_text
2 years ago
8.5 kB
16
Indexable
1 #include "header.h"
2
3 header *create_header(struct stat sb, char *path){
4 struct header *curr_header;
5 struct passwd *file_pwd;
6 struct group *file_group;
7 char *size8_buff, *size12_buff, *header_field;
8 int chksum_val;
9
10 /* Initialize header and string buffers */
11 curr_header = malloc(sizeof(header));
12 size8_buff = malloc(sizeof(char) * 8);
13 size12_buff = malloc(sizeof(char) * 12);
14
15 /* Check if malloc failed */
16 if(curr_header == NULL || size8_buff == NULL || size12_buff == NULL){
17 perror("malloc");
18 exit(EXIT_FAILURE);
19 }
20
21 /* Call function that packs name and prefix fields */
22 if(pack_name_and_prefix(path, curr_header) == -1){
23 return NULL;
24 }
25
26 /* Write mode as an octal num and store in header */
27 header_field = duplicate_buff(size8_buff);
28 if(snprintf(header_field, MODE_SIZE, "%0o", (unsigned int) sb.st_mode) < 0){
29 perror("word overflow");
30 }
31 curr_header->mode = header_field;
32
33 /* Write uid as an octal num and store in header */
34 header_field = duplicate_buff(size8_buff);
35 if(snprintf(header_field, UID_SIZE, "%0o", (unsigned int) sb.st_uid) < 0){
36 perror("word overflow");
37 }
38 curr_header->uid = header_field;
39
40 /* Write gid as an octal num and store in header */
41 header_field = duplicate_buff(size8_buff);
42 if(snprintf(header_field, GID_SIZE, "%0o", (unsigned int) sb.st_gid) < 0){
43 perror("word overflow");
44 }
45 curr_header->gid = header_field;
46
47 /* Write size as an octal num and store in header */
48 header_field = duplicate_buff(size12_buff);
49 if(snprintf(header_field, FILESIZE_SIZE, "%0o", (unsigned int) sb.st_size)
50 < 0){
51 perror("word overflow");
52 }
53 curr_header->size = header_field;
54
55 /* Write mtime as an octal num and store in header */
56 header_field = duplicate_buff(size12_buff);
57 if(snprintf(header_field, MTIME_SIZE, "%0o", (unsigned int) sb.st_mtime)
58 < 0){
59 perror("word overflow");
60 }
61 curr_header->mtime = header_field;
62
63 if(S_ISREG(sb.st_mode)){
64 curr_header->typeflag = '0';
65 }
66 else if(S_ISDIR(sb.st_mode)){
67 curr_header->typeflag = '5';
68 }
69 else if (S_ISLNK(sb.st_mode)){
70 curr_header->typeflag = '2';
71 }
72 else{
73 curr_header->typeflag = '\0';
74 }
75
76 /* FIX THIS LATER */
77 if(S_ISLNK(sb.st_mode)){
78 curr_header->linkname = NULL;
79 }
80 else{
81 curr_header->linkname = NULL;
82 }
83
84 /* Adding constant header fields */
85 curr_header->magic = "ustar";
86 curr_header->version = "00";
87 curr_header->devmajor = NULL;
88 curr_header->devminor = NULL;
89
90 /* Get user password and group fro user name and group name */
91 file_pwd = getpwuid(sb.st_uid);
92
93 if(file_pwd == NULL){
94 perror("why are you are here pwd");
95 exit(EXIT_FAILURE);
96 }
97
98 file_group = getgrgid(sb.st_gid);
99
100 if(file_group == NULL){
101 perror("IDK group");
102 exit(EXIT_FAILURE);
103 }
104
105 /* Assign user name and group name */
106 curr_header->uname = file_pwd->pw_name;
107 curr_header->gname = file_group->gr_name;
108
109 printf("%s user\n", curr_header->uname);
110 printf("%s group \n", curr_header->gname);
111 printf("%s magic \n", curr_header->magic);
112
113 /* Write chksum as an octal num and store in header */
114 header_field = duplicate_buff(size8_buff);
115 chksum_val = get_chksum_val(sb, path, file_pwd, file_group);
116 if(snprintf(header_field, CHKSUM_SIZE, "%0o", chksum_val) < 0){
117 perror("word overflow");
118 }
119 curr_header->chksum = header_field;
120
121 free(size8_buff);
122 free(size12_buff);
123
124 return curr_header;
125 }
126
127 char *duplicate_buff(char *buff){
128 char *header_field;
129
130 /* Duplicate buff and exit on failure */
131 if((header_field = strdup(buff)) == NULL){
132 perror("strdup");
133 exit(EXIT_FAILURE);
134 }
135
136 return header_field;
137 }
138
139 int pack_name_and_prefix(char *path, header *curr_header){
140 char *name_buff, *prefix_buff;
141 size_t path_len;
142 int i;
143
144 prefix_buff = malloc(sizeof(char) * PREFIX_SIZE);
145 name_buff = malloc(sizeof(char) * NAME_SIZE);
146
147 /* Check if malloc failed */
148 if(name_buff == NULL || prefix_buff == NULL){
149 perror("malloc");
150 exit(EXIT_FAILURE);
151 }
152
153 path_len = strlen(path);
154
155 /* Pack name and prefix fields */
156 if(path_len >= MAX_NAME_LEN){
157 perror("file name too long");
158 return -1;
159 }
160 else if(path_len < NAME_SIZE){
161 /* If name fits in name block */
162 if((curr_header->name = strdup(path)) == NULL){
163 perror("strdup");
164 exit(EXIT_FAILURE);
165 }
166
167 curr_header->prefix = NULL;
168 }
169 else if(path_len == NAME_SIZE){
170 /* If name is exactly 100 chars decide if it goes in prefix or name */
171 for(i = 0; i < NAME_SIZE; i++){
172 if(path[i] == '\0'){
173 curr_header->name = NULL;
174
175 if((curr_header->prefix = strdup(path)) == NULL){
176 perror("strdup");
177 exit(EXIT_FAILURE);
178 }
179 }
180 else if(path[i] == '/'){
181 if((curr_header->name = strdup(path)) == NULL){
182 perror("strdup");
183 exit(EXIT_FAILURE);
184 }
185
186 curr_header->prefix = NULL;
187 break;
188 }
189 }
190 }
191 else{
192 /* If name is exactly 100 chars decide if it goes in prefix or name */
193 for(i = path_len - NAME_SIZE; i < path_len; i++){
194 if(path[i] == '\0'){
195 perror("unable to construct header.");
196 return -1;
197 }
198 else if(path[i] == '/'){
199 /* Split the path and copy each part to its respective field */
200 strncpy(prefix_buff, path, i);
201 strncpy(name_buff, &path[i + 1], path_len - i);
202
203 /* Add null char to prefix */
204 prefix_buff[i] = '\0';
205
206 /* Realloc prefix to exact length */
207 if((prefix_buff = realloc(prefix_buff, i + 1)) == NULL){
208 perror("realloc");
209 exit(EXIT_FAILURE);
210 }
211
212 /* Realloc name to exact length */
213 if((name_buff = realloc(name_buff, path_len - i)) == NULL){
214 perror("realloc");
215 exit(EXIT_FAILURE);
216 }
217
218 /* Set name and prefix fields */
219 curr_header->name = name_buff;
220 curr_header->prefix = prefix_buff;
221
222 break;
223 }
224 }
225 }
226
227 return 0;
228 }
229
230 unsigned int get_chksum_val(struct stat sb, char *name, struct passwd *pw,
231 struct group *gr){
232 unsigned int chksum_val = 0;
233 int i;
234
235 chksum_val += (unsigned int) sb.st_mode;
236 chksum_val += (unsigned int) sb.st_uid;
237 chksum_val += (unsigned int) sb.st_gid;
238 chksum_val += (unsigned int) sb.st_size;
239 chksum_val += (unsigned int) sb.st_mtime;
240
241 for(i = 0; i < strlen(name); i++){
242 chksum_val += name[i];
243 }
244
245 for(i = 0; i < strlen(pw->pw_name); i++){
246 chksum_val += pw->pw_name[i];
247 }
248
249 for(i = 0; i < strlen(gr->gr_name); i++){
250 chksum_val += gr->gr_name[i];
251 }
252
253 return chksum_val;
254 }
254,1 BotEditor is loading...
Leave a Comment