header.c
unknown
plain_text
a year ago
8.5 kB
6
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 Bot
Editor is loading...
Leave a Comment