/* Use dir_namev() to find the vnode of the directory containing the dir to be * removed. Then call the containing dir's rmdir v_op. The rmdir v_op will * return an error if the dir to be removed does not exist or is not empty, so * you don't need to worry about that here. Return the value of the v_op, * or an error. * * Error cases you must handle for this function at the VFS level: * o EINVAL * path has "." as its final component. * o ENOTEMPTY * path has ".." as its final component. * o ENOENT * A directory component in path does not exist. * o ENOTDIR * A component used as a directory in path is not, in fact, a directory. * o ENAMETOOLONG * A component of path was too long. */ int do_rmdir(const char *path) { /* NOT_YET_IMPLEMENTED("VFS: do_rmdir"); */ size_t namelen; const char *name; vnode_t *base; vnode_t *res_vnode, *result; int tempLookup = 0; dbg(DBG_PRINT, "(GRADING2B)\n"); /* if (strlen(path) > MAXPATHLEN) { dbg(DBG_ERROR, "1\n"); return -ENAMETOOLONG; }*/ /* Base passed NULL since dir_namev can handle accordingly */ int retdir_namev = dir_namev(path, &namelen, &name, NULL, &res_vnode); if (retdir_namev != 0) { dbg(DBG_PRINT, "(GRADING2B)\n"); return retdir_namev; } if (name_match(".", name, namelen)) { dbg(DBG_PRINT, "(GRADING2B)\n"); vput(res_vnode); return -EINVAL; } if (name_match("..", name, namelen)) { dbg(DBG_PRINT, "(GRADING2B)\n"); vput(res_vnode); return -ENOTEMPTY; } if (strlen(name) > NAME_LEN) { dbg(DBG_ERROR, "5\n"); vput(res_vnode); return -ENAMETOOLONG; } if (0 == retdir_namev) { dbg(DBG_PRINT, "(GRADING2B)\n"); vput(res_vnode); tempLookup = lookup(res_vnode, name, namelen, &result); KASSERT(NULL != (res_vnode)->vn_ops->rmdir); dbg(DBG_PRINT, "(GRADING2A 3.d)\n"); int ret_rmdir = (res_vnode)->vn_ops->rmdir(res_vnode, name, namelen); if (ret_rmdir == 0 && result != NULL) { dbg(DBG_PRINT, "(GRADING2B)\n"); vput(result); } else if (tempLookup == 0 && result != NULL) { dbg(DBG_PRINT, "(GRADING2B)\n"); vput(result); } return ret_rmdir; } return 0; }
static int scan_file (char *str, int fd, register struct termcap_buffer *bufp) { register char *end; bufp->ptr = bufp->beg; bufp->full = 0; bufp->ateof = 0; *bufp->ptr = '\0'; lseek (fd, 0L, 0); while (!bufp->ateof) { /* Read a line into the buffer. */ end = NULL; do { /* if it is continued, append another line to it, until a non-continued line ends. */ end = gobble_line (fd, bufp, end); } while (!bufp->ateof && end[-2] == '\\'); if (*bufp->ptr != '#' && name_match (bufp->ptr, str)) return 1; /* Discard the line just processed. */ bufp->ptr = end; } return 0; }
int s5_find_dirent(vnode_t *vnode, const char *name, size_t namelen) { dbg_print("s5_find_dirent: Searching for Dir of Name: %s, Length: %i\n", name,namelen); s5_dirent_t traverse_dir; uint32_t offset = 0; int read = s5_read_file(vnode, offset, (char *) &traverse_dir, sizeof(s5_dirent_t)); /* Loop through the inode blocks until the dirent is found. */ while (read > 0) { dbg_print("s5_find_dirent: Temp Name: %s\n",traverse_dir.s5d_name); /* Once found, return. */ if (name_match(traverse_dir.s5d_name, name, namelen)) { dbg_print("s5_find_dirent: Found Directory!\n"); return traverse_dir.s5d_inode; } offset += sizeof(s5_dirent_t); read = s5_read_file(vnode, offset, (char *) &traverse_dir, sizeof(s5_dirent_t)); } /* If the function has not returned by this point, then dirent with parameter name DNE. */ dbg_print("s5_find_dirent: Directory Not Found :(\n"); return -ENOENT; }
int module_run(char* name) { // Get just name part - not full path char *s = strrchr(name,'/'); if (s) name = s + 1; int i; for (i=0; i<MAX_SIMPLE_MODULE; i++) { // Check if module loaded (otherwise name not valid) if (*h_run[i].lib != h_run[i].default_lib) { if (name_match(name,h_run[i].name)) { // Already loaded return (*h_run[i].lib)->run(); } } } for (i=0; i<MAX_SIMPLE_MODULE; i++) { // Look for empty slot if (*h_run[i].lib == h_run[i].default_lib) { // Found space - run module strcpy(h_run[i].name,name); return (*h_run[i].lib)->run(); } } // Error - no space module_run_error(LANG_MODULE_NO_SPACE, name); return -1; }
/* This takes a base 'dir', a 'name', its 'len', and a result vnode. * Most of the work should be done by the vnode's implementation * specific lookup() function, but you may want to special case * "." and/or ".." here depnding on your implementation. * * If dir has no lookup(), return -ENOTDIR. * * Note: returns with the vnode refcount on *result incremented. */ int lookup(vnode_t *dir, const char *name, size_t len, vnode_t **result) { /* VFS {{{ */ KASSERT(NULL != dir); KASSERT(NULL != name); KASSERT(NULL != result); if (dir->vn_ops->lookup == NULL) { return -ENOTDIR; } if (0 == len) { vref(dir); *result = dir; return 0; } #ifdef __MOUNTING__ if (name_match("..", name, len)) { if (dir->vn_fs->fs_root == dir) { vnode_t *mtpt = dir->vn_fs->fs_mtpt; return mtpt->vn_ops->lookup(mtpt, name, len, result); } } #endif return dir->vn_ops->lookup(dir, name, len, result); /* VFS }}} */ return 0; }
static int ramfs_unlink(vnode_t *dir, const char *name, size_t namelen) { vnode_t *vn; int ret; off_t i; ramfs_dirent_t *entry; ret = ramfs_lookup(dir, name, namelen, &vn); KASSERT(0 == ret); KASSERT(!S_ISDIR(vn->vn_mode)); /* And then remove the entry from the directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (name_match(entry->rd_name, name, namelen)) { entry->rd_name[0] = '\0'; break; } } VNODE_TO_RAMFSINODE(dir)->rf_size -= sizeof(ramfs_dirent_t); VNODE_TO_RAMFSINODE(vn)->rf_linkcount--; vput(vn); return 0; }
static int ramfs_rmdir(vnode_t *dir, const char *name, size_t name_len) { vnode_t *vn; int ret; off_t i; ramfs_dirent_t *entry; KASSERT(!name_match(".", name, name_len) && !name_match("..", name, name_len)); if ((ret = ramfs_lookup(dir, name, name_len, &vn)) != 0) return ret; if (!S_ISDIR(vn->vn_mode)) { vput(vn); return -ENOTDIR; } /* We have to make sure that this directory is empty */ entry = VNODE_TO_DIRENT(vn); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (!strcmp(entry->rd_name, ".") || !strcmp(entry->rd_name, "..")) continue; if (entry->rd_name[0]) { vput(vn); return -ENOTEMPTY; } } /* Finally, remove the entry from the parent directory */ entry = VNODE_TO_DIRENT(dir); for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (name_match(entry->rd_name, name, name_len)) { entry->rd_name[0] = '\0'; break; } } VNODE_TO_RAMFSINODE(dir)->rf_size -= sizeof(ramfs_dirent_t); VNODE_TO_RAMFSINODE(vn)->rf_linkcount--; vput(vn); return 0; }
/* * Locate the directory entry in the given inode with the given name, * and delete it. If there is no entry with the given name, return * -ENOENT. * * In order to ensure that the directory entries are contiguous in the * directory file, you will need to move the last directory entry into * the remove dirent's place. * * When this function returns, the inode refcount on the removed file * should be decremented. * * It would be a nice extension to free blocks from the end of the * directory file which are no longer needed. * * Don't forget to dirty appropriate blocks! * * You probably want to use vget(), vput(), s5_read_file(), * s5_write_file(), and s5_dirty_inode(). */ int s5_remove_dirent(vnode_t *vnode, const char *name, size_t namelen) { dbg_print("s5_remove_dirent: Removing Dirent"); int inode = s5_find_dirent(vnode,name,namelen); if(inode == -ENOENT) { dbg_print("s5_remove_dirent: ERROR, Directory not found"); return -ENOENT; } else { vnode_t* vnode_to_remove = vget(vnode->vn_fs,inode); s5_inode_t* inode_to_remove = VNODE_TO_S5INODE(vnode_to_remove); inode_to_remove->s5_linkcount--; vput(vnode_to_remove); /* Need to get the offset of where the dirent is */ int total_count = 0; int dir_index = 0; /* Loop through the inode blocks until the dirent is found. */ s5_dirent_t traverse_dir; while (s5_read_file(vnode, dir_index * sizeof(s5_dirent_t), (char *) &traverse_dir, sizeof(s5_dirent_t)) > 0) { /* Once found, return. */ if (name_match(traverse_dir.s5d_name, name, namelen)) { dir_index = total_count; } total_count++; } total_count--; if(dir_index != total_count) { /* swap dir with last */ char* last_buffer = kmalloc(sizeof(s5_dirent_t)); s5_dirent_t* dirent = (s5_dirent_t*)last_buffer; int read = s5_read_file(vnode,vnode->vn_len - sizeof(s5_dirent_t),last_buffer,sizeof(s5_dirent_t)); KASSERT(read == sizeof(s5_dirent_t)); int write = s5_write_file(vnode, dir_index * sizeof(s5_dirent_t), last_buffer, sizeof(s5_dirent_t)); KASSERT(write == sizeof(s5_dirent_t)); } s5_inode_t* inode = VNODE_TO_S5INODE(vnode); vnode->vn_len -= sizeof(s5_dirent_t); inode->s5_size -= sizeof(s5_dirent_t); s5_dirty_inode(VNODE_TO_S5FS(vnode),inode); return 0; } /* NOT_YET_IMPLEMENTED("S5FS: s5_remove_dirent"); * return -1; */ }
bool Unification::unify(Predicate& p,Predicate& q,VarBinding& original_bindings){ bool match = false; VarBinding bindings(original_bindings); if (name_match(p,q)){ match = arguments_match(p,q,bindings); } if (match) original_bindings = bindings; return match; }
/* * s5_find_dirent: * Locate the directory entry in the given inode with the given name, * and return its inode number. * return: the inode number, if there is no entry with the given * name, return -ENOENT. * param *vnode: the pointer to the vnode object * param name: name string * param namelen: the length of name * return: the inode number, or -ENOENT if there is no entry */ int s5_find_dirent(vnode_t *vnode, const char *name, size_t namelen) { dbg(DBG_S5FS, "{\n"); KASSERT(vnode != NULL); KASSERT(namelen <= S5_NAME_LEN - 1); KASSERT(name != NULL); KASSERT((uint32_t)vnode->vn_len == VNODE_TO_S5INODE(vnode)->s5_size); if (!namelen) { return 0; } s5_dirent_t tmp; off_t offset = 0; while (1) { int bytes = s5_read_file(vnode, offset, (char*)(&tmp), sizeof(s5_dirent_t)); if (bytes < 0) { /* error */ dbg(DBG_S5FS, "}(error code returned)\n"); return bytes; } else if (bytes == 0) { dbg(DBG_S5FS, "}(error code returned)\n"); return -ENOENT; } else if (bytes != sizeof(s5_dirent_t)) { dbg(DBG_S5FS, "}(error code returned)\n"); return -1; /* not sure */ } else { if (name_match(tmp.s5d_name, name, namelen)) { dbg(DBG_S5FS, "}\n"); return tmp.s5d_inode; } else { offset+= sizeof(s5_dirent_t); } } } KASSERT(0); }
static int ramfs_lookup(vnode_t *dir, const char *name, size_t namelen, vnode_t **result) { off_t i; ramfs_inode_t *inode = VNODE_TO_RAMFSINODE(dir); ramfs_dirent_t *entry = (ramfs_dirent_t *)inode->rf_mem; for (i = 0; i < RAMFS_MAX_DIRENT; i++, entry++) { if (name_match(entry->rd_name, name, namelen)) { *result = vget(dir->vn_fs, entry->rd_ino); return 0; } } return -ENOENT; }
/* * s5_link: * Create a new directory entry in directory 'parent' with the given name, which * refers to the same file as 'child'. * param *parent: the pointer to the parent vnode object of the vnode child * param *child: the pointer to the child vnode object * param *name: name string * param namelen: the length of the name * return: bytes that has been added to the parent's block, or negative number * on failure */ int s5_link(vnode_t *parent, vnode_t *child, const char *name, size_t namelen) { dbg(DBG_S5FS, "{\n"); KASSERT(parent != NULL); KASSERT(child != NULL); KASSERT(name != NULL); KASSERT(S_ISDIR(parent->vn_mode)); KASSERT((uint32_t)parent->vn_len == VNODE_TO_S5INODE(parent)->s5_size); KASSERT((uint32_t)child->vn_len == VNODE_TO_S5INODE(child)->s5_size); int exist = s5_find_dirent(parent, name, namelen); if (exist >= 0) { return -1; } else { s5_inode_t* child_inode = VNODE_TO_S5INODE(child); ino_t child_inode_num = child_inode->s5_number; KASSERT(child_inode_num == child->vn_vno); s5_dirent_t dirent; memcpy(dirent.s5d_name, name, S5_NAME_LEN); KASSERT(dirent.s5d_name[namelen] == '\0'); dirent.s5d_inode = child_inode_num; s5_inode_t* inode_parent = VNODE_TO_S5INODE(parent); KASSERT((uint32_t)parent->vn_len == inode_parent->s5_size); int bytes = s5_write_file(parent, inode_parent->s5_size, (char*)&dirent, sizeof(s5_dirent_t)); if (bytes == sizeof(s5_dirent_t)) { /* If not '.' or '..', we need to add the link */ if (!name_match(name, ".", 1)) { child_inode->s5_linkcount++; s5_dirty_inode(VNODE_TO_S5FS(child), child_inode); } dbg(DBG_S5FS, "}\n"); return 0; } return bytes; } }
void iterate_over_minimal_symbols (struct objfile *objf, const lookup_name_info &lookup_name, gdb::function_view<bool (struct minimal_symbol *)> callback) { /* The first pass is over the ordinary hash table. */ { const char *name = linkage_name_str (lookup_name); unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; auto *mangled_cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp); for (minimal_symbol *iter = objf->per_bfd->msymbol_hash[hash]; iter != NULL; iter = iter->hash_next) { if (mangled_cmp (MSYMBOL_LINKAGE_NAME (iter), name) == 0) if (callback (iter)) return; } } /* The second pass is over the demangled table. Once for each language in the demangled hash names table (usually just zero or one). */ for (auto lang : objf->per_bfd->demangled_hash_languages) { const language_defn *lang_def = language_def (lang); symbol_name_matcher_ftype *name_match = get_symbol_name_matcher (lang_def, lookup_name); unsigned int hash = lookup_name.search_name_hash (lang) % MINIMAL_SYMBOL_HASH_SIZE; for (minimal_symbol *iter = objf->per_bfd->msymbol_demangled_hash[hash]; iter != NULL; iter = iter->demangled_hash_next) if (name_match (MSYMBOL_SEARCH_NAME (iter), lookup_name, NULL)) if (callback (iter)) return; } }
static int s5_find_dirent_helper(vnode_t *vnode, const char *name, size_t namelen, off_t *offset, int *ino){ s5_dirent_t dirents[NDIRENTS]; off_t seek = 0; while (seek < vnode->vn_len){ int read_res = s5_read_file(vnode, seek, (char *) dirents, NDIRENTS * sizeof(s5_dirent_t)); KASSERT(seek + read_res <= vnode->vn_len); if (read_res < 0){ dbg(DBG_S5FS, "error getting dirents\n"); return read_res; } int dirents_read = read_res / sizeof(s5_dirent_t); int i; for (i = 0; i < dirents_read; i++){ if (name_match(dirents[i].s5d_name, name, namelen)){ if (offset != NULL){ *offset = seek + (i * sizeof(s5_dirent_t)); } if (ino != NULL){ *ino = dirents[i].s5d_inode; } return 0; } } seek += read_res; } return -ENOENT; }
/* * s5_remove_dirent: * Locate the directory entry in the given inode with the given name, * and delete it. If there is no entry with the given name, return * -ENOENT. * param *vnode: the pointer to the vnode object * param *name: the name string * param namelen: the length of the name string * return: 0 on success and -ENOENT if there is no entry */ int s5_remove_dirent(vnode_t *vnode, const char *name, size_t namelen) { dbg(DBG_S5FS, "{\n"); KASSERT(vnode != NULL); KASSERT(name != NULL); KASSERT(namelen <= S5_NAME_LEN - 1); KASSERT((uint32_t)vnode->vn_len == VNODE_TO_S5INODE(vnode)->s5_size); KASSERT(vnode->vn_len%sizeof(s5_dirent_t) == 0); s5_dirent_t tmp; off_t offset = 0; while (1) { int bytes = s5_read_file(vnode, offset, (char*)&tmp, sizeof(s5_dirent_t)); if (bytes < 0) { return bytes; } else if (bytes == 0) { return -ENOENT; } else if (bytes != sizeof(s5_dirent_t)) { return -1; } else { if (name_match(tmp.s5d_name, name, namelen)) { if (offset + (off_t)sizeof(s5_dirent_t) < vnode->vn_len) { s5_dirent_t last_dirent; int bytes2 = s5_read_file(vnode, vnode->vn_len - sizeof(s5_dirent_t), (char*)&last_dirent, sizeof(s5_dirent_t)); if (bytes2 < 0) { return bytes2; } else if (bytes2 != sizeof(s5_dirent_t)) { return -1; } else { bytes2 = s5_write_file(vnode, offset, (char*)&last_dirent, sizeof(s5_dirent_t)); if (bytes2 < 0) { return bytes2; } } } vnode->vn_len -= sizeof(s5_dirent_t); s5_inode_t* inode = VNODE_TO_S5INODE(vnode ); inode->s5_size = vnode->vn_len; s5_dirty_inode(VNODE_TO_S5FS(vnode),inode); vnode_t* vn = vget(vnode->vn_fs,tmp.s5d_inode); KASSERT(vn); s5_inode_t* remove_inode = VNODE_TO_S5INODE(vn); remove_inode->s5_linkcount--; s5_dirty_inode(FS_TO_S5FS(vn->vn_fs), remove_inode); vput(vn); return 0; } else { offset+= sizeof(s5_dirent_t); } } } KASSERT(0); }
/* print test and return true on failure */ static int test(const char *p1, const char *p2, int expect) { int match = name_match(p1, p2); if (verbose) printf("name_match(\"%s\", \"%s\") == %d (%d expected)\n", p1, p2, match, expect); return expect != match; }
/* Use dir_namev() to find the vnode of the directory containing the dir to be * removed. Then call the containing dir's rmdir v_op. The rmdir v_op will * return an error if the dir to be removed does not exist or is not empty, so * you don't need to worry about that here. Return the value of the v_op, * or an error. * * Error cases you must handle for this function at the VFS level: * o EINVAL * path has "." as its final component. * o ENOTEMPTY * path has ".." as its final component. * o ENOENT * A directory component in path does not exist. * o ENOTDIR * A component used as a directory in path is not, in fact, a directory. * o ENAMETOOLONG * A component of path was too long. */ int do_rmdir(const char *path) { /*NOT_YET_IMPLEMENTED("VFS: do_rmdir");*/ /*dbg(DBG_PRINT,"Entering do_rmdir\n"); */ int errcode; const char *name = NULL; size_t len = 0; vnode_t *res_vnode; vnode_t *result_vnode; dbg(DBG_PRINT,"(GRADING2C)\n"); errcode=dir_namev(path,&len,&name,NULL,&res_vnode); if(errcode < 0) { dbg(DBG_PRINT,"dir_namev error\n"); dbg(DBG_PRINT,"(GRADING2C)\n"); return errcode; } if(name_match(".",name,len)) { vput(res_vnode); /*dbg(DBG_PRINT,". as the final component\n");*/ dbg(DBG_PRINT,"(GRADING2C)\n"); return -EINVAL; } if(name_match("..",name,len)) { vput(res_vnode); dbg(DBG_PRINT,"(GRADING2C)\n"); /*dbg(DBG_PRINT,".. as the final component\n"); */ return -ENOTEMPTY; } if(/*(dir->vn_ops->lookup == NULL) ||*/ !S_ISDIR(res_vnode->vn_mode)) { dbg(DBG_PRINT,"(GRADING2C) Not a directory as lookup() null or S_ISDIR null\n"); dbg(DBG_PRINT,"(GRADING2C 2)\n"); vput(res_vnode); return -ENOTDIR; } /*vput(res_vnode); errcode=lookup(res_vnode,name,len,&result_vnode); dbg(DBG_PRINT,"\n dir = %d\n",res_vnode->vn_vno); dbg(DBG_PRINT,"\nname = %s\n",name); dbg(DBG_PRINT,"\nERRCODE = %d\n",errcode); */ /* if(errcode == -ENOENT) { dbg(DBG_PRINT," ENOENT Leaving rmdir ****************************************\n"); dbg(DBG_PRINT,"(GRADING2C)\n"); return -ENOENT; } if(errcode == -ENOTDIR) { dbg(DBG_PRINT,"(GRADING2C)\n"); dbg(DBG_PRINT,"ENOTDIR Leaving rmdir ****************************************\n"); return -ENOTDIR; } */ /*if(errcode < 0) { dbg(DBG_PRINT,"dir_namev error\n"); dbg(DBG_PRINT,"(GRADING2C V32)\n"); return errcode; } */ KASSERT(NULL != res_vnode->vn_ops->rmdir); dbg(DBG_PRINT,"(GRADING2A 3.d)\n"); dbg(DBG_PRINT,"(GRADING2C)\n"); int retvar; retvar = res_vnode->vn_ops->rmdir(res_vnode, name, len); vput(res_vnode); /* dbg(DBG_PRINT,"Exiting do_rmdir\n"); */ return retvar; }
void read_and (void (*do_something) ()) { enum read_header status = HEADER_STILL_UNREAD; enum read_header prev_status; char save_typeflag; name_gather (); open_archive (ACCESS_READ); while (1) { prev_status = status; status = read_header (); switch (status) { case HEADER_STILL_UNREAD: abort (); case HEADER_SUCCESS: /* Valid header. We should decode next field (mode) first. Ensure incoming names are null terminated. */ /* FIXME: This is a quick kludge before 1.12 goes out. */ current_stat.st_mtime = from_oct (1 + 12, current_header->header.mtime); if (!name_match (current_file_name) || current_stat.st_mtime < newer_mtime_option || (exclude_option && check_exclude (current_file_name))) { int isextended = 0; if (current_header->header.typeflag == GNUTYPE_VOLHDR || current_header->header.typeflag == GNUTYPE_MULTIVOL || current_header->header.typeflag == GNUTYPE_NAMES) { (*do_something) (); continue; } if (show_omitted_dirs_option && current_header->header.typeflag == DIRTYPE) WARN ((0, 0, _("Omitting %s"), current_file_name)); /* Skip past it in the archive. */ if (current_header->oldgnu_header.isextended) isextended = 1; save_typeflag = current_header->header.typeflag; set_next_block_after (current_header); if (isextended) { #if 0 union block *exhdr; while (1) { exhdr = find_next_block (); if (!exhdr->sparse_header.isextended) { set_next_block_after (exhdr); break; } } set_next_block_after (exhdr); #endif skip_extended_headers (); } /* Skip to the next header on the archive. */ if (save_typeflag != DIRTYPE) skip_file ((long long) current_stat.st_size); continue; } (*do_something) (); continue; case HEADER_ZERO_BLOCK: if (block_number_option) fprintf (stdlis, _("block %10ld: ** Block of NULs **\n"), current_block_ordinal ()); set_next_block_after (current_header); status = prev_status; if (ignore_zeros_option) continue; break; case HEADER_END_OF_FILE: if (block_number_option) fprintf (stdlis, _("block %10ld: ** End of File **\n"), current_block_ordinal ()); break; case HEADER_FAILURE: /* If the previous header was good, tell them that we are skipping bad ones. */ set_next_block_after (current_header); switch (prev_status) { case HEADER_STILL_UNREAD: WARN ((0, 0, _("Could not extract file(s); file might not be a tar archive"))); /* Fall through. */ case HEADER_ZERO_BLOCK: case HEADER_SUCCESS: WARN ((0, 0, _("Skipping to next file header"))); break; case HEADER_END_OF_FILE: case HEADER_FAILURE: /* We are in the middle of a cascade of errors. */ break; } continue; } break; } apply_delayed_set_stat (); close_archive (); names_notfound (); /* print names not found */ }
int read_archive() #endif { Stat sb; char name[PATH_MAX + 1]; int match; int pad; name_gather(); /* get names from command line */ name[0] = '\0'; while (get_header(name, &sb) == 0) { match = name_match(name) ^ f_reverse_match; if (f_list) { /* only wanted a table of contents */ if (match) { print_entry(name, &sb); } if (((ar_format == TAR) ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) : buf_skip((OFFSET) sb.sb_size)) < 0) { warn(name, "File data is corrupt"); } } else if (match) { if (rplhead != (Replstr *)NULL) { rpl_name(name); if (strlen(name) == 0) { continue; } } if (get_disposition("extract", name) || get_newname(name, sizeof(name))) { /* skip file... */ if (((ar_format == TAR) ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) : buf_skip((OFFSET) sb.sb_size)) < 0) { warn(name, "File data is corrupt"); } continue; } if (inentry(name, &sb) < 0) { warn(name, "File data is corrupt"); } if (f_verbose) { print_entry(name, &sb); } if (ar_format == TAR && sb.sb_nlink > 1) { /* * This kludge makes sure that the link table is cleared * before attempting to process any other links. */ if (sb.sb_nlink > 1) { linkfrom(name, &sb); } } if (ar_format == TAR && (pad = sb.sb_size % BLOCKSIZE) != 0) { pad = BLOCKSIZE - pad; buf_skip((OFFSET) pad); } } else { if (((ar_format == TAR) ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) : buf_skip((OFFSET) sb.sb_size)) < 0) { warn(name, "File data is corrupt"); } } } close_archive(); }