char *t_Str::strip(const char *chars, char *str, size_t len) { len = strtrim(chars, str, len); if(!len) return str; return ifind(chars, str, len); }
size_t CPLString::ifind( const std::string & str, size_t pos ) const { return ifind( str.c_str(), pos ); }
/* Implement the diskfs_lookup callback from the diskfs library. See <hurd/diskfs.h> for the interface specification. */ error_t diskfs_lookup_hard (struct node *dp, const char *name, enum lookup_type type, struct node **npp, struct dirstat *ds, struct protid *cred) { error_t err; ino_t inum; int namelen; int spec_dotdot; struct node *np = 0; int retry_dotdot = 0; vm_prot_t prot = (type == LOOKUP) ? VM_PROT_READ : (VM_PROT_READ | VM_PROT_WRITE); memory_object_t memobj; vm_address_t buf = 0; vm_size_t buflen = 0; int blockaddr; int idx, lastidx; int looped; if ((type == REMOVE) || (type == RENAME)) assert (npp); if (npp) *npp = 0; spec_dotdot = type & SPEC_DOTDOT; type &= ~SPEC_DOTDOT; namelen = strlen (name); if (namelen > FAT_NAME_MAX) return ENAMETOOLONG; try_again: if (ds) { ds->type = LOOKUP; ds->mapbuf = 0; ds->mapextent = 0; } if (buf) { munmap ((caddr_t) buf, buflen); buf = 0; } if (ds && (type == CREATE || type == RENAME)) ds->stat = LOOKING; /* Map in the directory contents. */ memobj = diskfs_get_filemap (dp, prot); if (memobj == MACH_PORT_NULL) return errno; buf = 0; /* We allow extra space in case we have to do an EXTEND. */ buflen = round_page (dp->dn_stat.st_size + DIRBLKSIZ); err = vm_map (mach_task_self (), &buf, buflen, 0, 1, memobj, 0, 0, prot, prot, 0); mach_port_deallocate (mach_task_self (), memobj); inum = 0; diskfs_set_node_atime (dp); /* Start the lookup at DP->dn->dir_idx. */ idx = dp->dn->dir_idx; if (idx << LOG2_DIRBLKSIZ > dp->dn_stat.st_size) idx = 0; /* just in case */ blockaddr = buf + (idx << LOG2_DIRBLKSIZ); looped = (idx == 0); lastidx = idx; if (lastidx == 0) lastidx = dp->dn_stat.st_size >> LOG2_DIRBLKSIZ; while (!looped || idx < lastidx) { err = dirscanblock (blockaddr, dp, idx, name, namelen, type, ds, &inum); if (!err) { dp->dn->dir_idx = idx; break; } if (err != ENOENT) { munmap ((caddr_t) buf, buflen); return err; } blockaddr += DIRBLKSIZ; idx++; if (blockaddr - buf >= dp->dn_stat.st_size && !looped) { /* We've gotten to the end; start back at the beginning. */ looped = 1; blockaddr = buf; idx = 0; } } diskfs_set_node_atime (dp); if (diskfs_synchronous) diskfs_node_update (dp, 1); /* If err is set here, it's ENOENT, and we don't want to think about that as an error yet. */ err = 0; if (inum && npp) { if (namelen != 2 || name[0] != '.' || name[1] != '.') { if (inum == dp->cache_id) { np = dp; diskfs_nref (np); } else { err = diskfs_cached_lookup_in_dirbuf (inum, &np, buf); if (err) goto out; } } /* We are looking up "..". */ /* Check to see if this is the root of the filesystem. */ else if (dp == diskfs_root_node) { err = EAGAIN; goto out; } /* We can't just do diskfs_cached_lookup, because we would then deadlock. So we do this. Ick. */ else if (retry_dotdot) { /* Check to see that we got the same answer as last time. */ if (inum != retry_dotdot) { /* Drop what we *thought* was .. (but isn't any more) and try *again*. */ diskfs_nput (np); mutex_unlock (&dp->lock); err = diskfs_cached_lookup_in_dirbuf (inum, &np, buf); mutex_lock (&dp->lock); if (err) goto out; retry_dotdot = inum; goto try_again; } /* Otherwise, we got it fine and np is already set properly. */ } else if (!spec_dotdot) { /* Lock them in the proper order, and then repeat the directory scan to see if this is still right. */ mutex_unlock (&dp->lock); err = diskfs_cached_lookup_in_dirbuf (inum, &np, buf); mutex_lock (&dp->lock); if (err) goto out; retry_dotdot = inum; goto try_again; } /* Here below are the spec dotdot cases. */ else if (type == RENAME || type == REMOVE) np = ifind (inum); else if (type == LOOKUP) { diskfs_nput (dp); err = diskfs_cached_lookup_in_dirbuf (inum, &np, buf); if (err) goto out; } else assert (0); } if ((type == CREATE || type == RENAME) && !inum && ds && ds->stat == LOOKING) { /* We didn't find any room, so mark ds to extend the dir. */ ds->type = CREATE; ds->stat = EXTEND; ds->idx = dp->dn_stat.st_size >> LOG2_DIRBLKSIZ; }