* Fill in the buffer pointed to by h with a tar format header. This buffer * must always have space for 512 characters, which is a requirement of * the tar format. */
| 111 | * the tar format. |
| 112 | */ |
| 113 | enum tarError |
| 114 | tarCreateHeader(char *h, const char *filename, const char *linktarget, |
| 115 | pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime) |
| 116 | { |
| 117 | if (strlen(filename) > 99) |
| 118 | return TAR_NAME_TOO_LONG; |
| 119 | |
| 120 | if (linktarget && strlen(linktarget) > 99) |
| 121 | return TAR_SYMLINK_TOO_LONG; |
| 122 | |
| 123 | memset(h, 0, 512); /* assume tar header size */ |
| 124 | |
| 125 | /* Name 100 */ |
| 126 | strlcpy(&h[0], filename, 100); |
| 127 | if (linktarget != NULL || S_ISDIR(mode)) |
| 128 | { |
| 129 | /* |
| 130 | * We only support symbolic links to directories, and this is |
| 131 | * indicated in the tar format by adding a slash at the end of the |
| 132 | * name, the same as for regular directories. |
| 133 | */ |
| 134 | int flen = strlen(filename); |
| 135 | |
| 136 | flen = Min(flen, 99); |
| 137 | h[flen] = '/'; |
| 138 | h[flen + 1] = '\0'; |
| 139 | } |
| 140 | |
| 141 | /* Mode 8 - this doesn't include the file type bits (S_IFMT) */ |
| 142 | print_tar_number(&h[100], 8, (mode & 07777)); |
| 143 | |
| 144 | /* User ID 8 */ |
| 145 | print_tar_number(&h[108], 8, uid); |
| 146 | |
| 147 | /* Group 8 */ |
| 148 | print_tar_number(&h[116], 8, gid); |
| 149 | |
| 150 | /* File size 12 */ |
| 151 | if (linktarget != NULL || S_ISDIR(mode)) |
| 152 | /* Symbolic link or directory has size zero */ |
| 153 | print_tar_number(&h[124], 12, 0); |
| 154 | else |
| 155 | print_tar_number(&h[124], 12, size); |
| 156 | |
| 157 | /* Mod Time 12 */ |
| 158 | print_tar_number(&h[136], 12, mtime); |
| 159 | |
| 160 | /* Checksum 8 cannot be calculated until we've filled all other fields */ |
| 161 | |
| 162 | if (linktarget != NULL) |
| 163 | { |
| 164 | /* Type - Symbolic link */ |
| 165 | h[156] = '2'; |
| 166 | /* Link Name 100 */ |
| 167 | strlcpy(&h[157], linktarget, 100); |
| 168 | } |
| 169 | else if (S_ISDIR(mode)) |
| 170 | { |
no test coverage detected