Header analysis is done by the add_tar_entry() function. If this looks a little bit familiar it's because the code is based on the pathwalk() function from the RAM-disk resource manager, with logic added to process the tar file header.
static int add_tar_entry (cfs_attr_t *a, off_t off, ustar_t *t, char *tarfile) { des_t output [_POSIX_PATH_MAX]; int nels; char *p; int i; int mode; // 1) first entry is the mount point output [0].attr = a; output [0].name = NULL; // 2) break apart the pathname at the slashes nels = 1; for (p = strtok (t -> name, "/"); p; p = strtok (NULL, "/"), nels++) { if (nels >= _POSIX_PATH_MAX) { return (E2BIG); } output [nels].name = p; output [nels].attr = NULL; } // 3) analyze each pathname component for (i = 1; i < nels; i++) { // 4) sanity check if (!S_ISDIR (output [i - 1].attr -> attr.mode)) { return (ENOTDIR); // effectively an internal error } // 5) check to see if the element exists... if (!(output [i].attr = search_dir (output [i].name, output [i-1].attr))) { mode = parse_mode (t); // 6) intermediate directory needs to be created... if (S_ISDIR (mode) || (i + 1 < nels)) { output [i].attr = cfs_a_mkdir (output [i - 1].attr, output [i].name, NULL); tar_to_attr (t, &output [i].attr -> attr); // kludge for implied "directories" if (S_ISREG (output [i].attr -> attr.mode)) { output [i].attr -> attr.mode = (output [i].attr -> attr.mode & ~S_IFREG) | S_IFDIR; } // 7) add a regular file } else if (S_ISREG (mode)) { output [i].attr = cfs_a_mkfile (output [i - 1].attr, output [i].name, NULL); tar_to_attr (t, &output [i].attr -> attr); output [i].attr -> nels = output [i].attr -> nalloc = 1; output [i].attr -> type.vfile.name = tarfile; output [i].attr -> type.vfile.off = off; // 8) add a symlink } else if (S_ISLNK (mode)) { output [i].attr = cfs_a_mksymlink (output [i - 1].attr, output [i].name, NULL); tar_to_attr (t, &output [i].attr -> attr); output [i].attr -> type.symlinkdata = strdup (t -> linkname); output [i].attr -> attr.nbytes = strlen (t -> linkname); } else { // code prints an error message here... return (EBADF); // effectively an internal error } } } return (EOK); }
The code walkthrough is: