header.c

mail@pastecode.io avatar
unknown
plain_text
2 months ago
8.5 kB
2
Indexable
Never
  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         Bot
Leave a Comment