void makeDir(char * newName){ char * parcialName = (char*)malloc(sizeof(25)); iNode * makeDir_current = current; iNode * posibleDir_current; int i,j,index; for( i = 0; newName[i] != '\0'; i++) //Parseo el string hasta el final { j = i; if ( newName[j] == '/' ) { i++; j++; } for( ; !(newName[j] == '/' || newName[j] == '\0'); j++); //Recorro paralelamente hasta encontrar o una / o un '/0' substr(parcialName, newName, i,j); if( ( posibleDir_current = search_directory(parcialName, makeDir_current) ) == NULL){ insert_directory(parcialName,makeDir_current); makeDir_current = search_directory(parcialName,makeDir_current); }else{ makeDir_current =posibleDir_current; } i=j-1; } return; }
int do_open(char * filename, int flags, int mode) { iNode * posible_file = search_directory(filename, current); int fd; if (posible_file != NULL) { if (posible_file->gid < currentUsr.group) return -2; if (posible_file->identifier == LINK) { posible_file = fs_get_inode(posible_file->link); } if ((fd = search_for_inode(posible_file->iNode_number)) != -1) { return fd; } else { return insert_fd(posible_file->iNode_number); } } else { if (flags == 0) { do_creat(filename, mode); } else { return -1; } } }
static UINT search_ini( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', 'f','r','o','m',' ', 'I','n','i','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ','\'','%','s','\'',0}; MSIRECORD *row; LPWSTR fileName, section, key; int field, type; WCHAR buf[MAX_PATH]; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord( package->db, query, sig->Name ); if (!row) { TRACE("failed to query IniLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } fileName = msi_dup_record_field(row, 2); section = msi_dup_record_field(row, 3); key = msi_dup_record_field(row, 4); field = MSI_RecordGetInteger(row, 5); type = MSI_RecordGetInteger(row, 6); if (field == MSI_NULL_INTEGER) field = 0; if (type == MSI_NULL_INTEGER) type = 0; GetPrivateProfileStringW(section, key, NULL, buf, MAX_PATH, fileName); if (buf[0]) { switch (type & 0x0f) { case msidbLocatorTypeDirectory: search_directory( package, sig, buf, 0, appValue ); break; case msidbLocatorTypeFileName: *appValue = search_file( package, buf, sig ); break; case msidbLocatorTypeRawValue: *appValue = get_ini_field(buf, field); break; } } msi_free(fileName); msi_free(section); msi_free(key); msiobj_release(&row->hdr); return ERROR_SUCCESS; }
/* Note we need the subject because we must check the ACL for any nested directories. */ INT64_T cfs_basic_search(const char *subject, const char *dir, const char *pattern, int flags, struct link * l, time_t stoptime) { char fullpath[CHIRP_PATH_MAX]; strcpy(fullpath, dir); path_remove_trailing_slashes(fullpath); /* this prevents double slashes from appearing in paths we examine. */ debug(D_DEBUG, "cfs_basic_search(subject = `%s', dir = `%s', pattern = `%s', flags = %d, ...)", subject, dir, pattern, flags); /* FIXME we should still check for literal paths to search since we can optimize that */ return search_directory(subject, fullpath + strlen(fullpath), fullpath, pattern, flags, l, stoptime); }
iNode * insert_file(char * name, int mode, iNode * current) { iNode * newFile = (iNode *) malloc(sizeof(iNode)); if ((newFile = search_directory(name, current)) != NULL) { return NULL; } newFile = fs_creat_inode(FILE, mode, 0, current); fs_insert_inode(newFile); insert_file_entry(newFile, current, name); return newFile; }
void search_directory(const gchar *path, GSList **list, int n_params, const gchar **mimes) { GFile *file = NULL; GFileInfo *next_file; GFileType type; GFileEnumerator *listing; const gchar *next_path; const gchar *file_mime; gchar *full_path = NULL; MediaInfo *media; guint i; file = g_file_new_for_path(path); type = g_file_query_file_type(file, G_FILE_QUERY_INFO_NONE, NULL); if (type == G_FILE_TYPE_DIRECTORY) { /* Enumerate children (needs less query flags!) */ listing = g_file_enumerate_children(file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, NULL); /* Lets go through them */ while ((next_file = g_file_enumerator_next_file(listing, NULL, NULL)) != NULL) { next_path = g_file_info_get_name(next_file); full_path = g_strdup_printf("%s/%s", path, next_path); /* Recurse if its a directory */ if (g_file_info_get_file_type(next_file) == G_FILE_TYPE_DIRECTORY) { search_directory(full_path, list, n_params, mimes); } else { /* Not exactly a regex but it'll do for now */ file_mime = g_file_info_get_content_type(next_file); for (i=0; i < n_params; i++) { if (g_str_has_prefix(file_mime, mimes[i])) { media = media_from_file(full_path, next_file, file_mime); /* Probably switch to a new struct in the future */ *list = g_slist_append(*list, media); } } } g_free(full_path); g_object_unref(next_file); full_path = NULL; } g_file_enumerator_close(listing, NULL, NULL); g_object_unref(listing); } g_object_unref(file); }
/* * Filename is actually null terminated. * (0, '\0') will be returned on file not found. Valid as block 0 contains FS info and thus will not be used for any useful data. */ struct basic_fileinfo search_directory(char *inode_base, unsigned int inode_num, struct parsed_filename *filename){ struct ext2_inode *current_inode = get_inode(inode_base, inode_num); unsigned int block_num = current_inode->i_block[0]; unsigned int cur_index_serviced = 0, cur_inode_index = 0; char *current_block = get_block(disk, block_num, 1024); struct ext2_dir_entry_2 *current = (struct ext2_dir_entry_2 *) current_block; while(cur_index_serviced < current_inode -> i_size){ current = (struct ext2_dir_entry_2 *) (current_block + (cur_index_serviced % 1024)); if (strlen(filename -> file_name) == current -> name_len && !strncmp(filename -> file_name, current -> name, strlen(filename -> file_name))){ if (!filename -> next){ struct basic_fileinfo current_file; current_file.inode = current -> inode; current_file.type = type_to_char(current -> file_type); free(filename -> file_name); free(filename); return current_file; } else{ struct parsed_filename *next = filename -> next; free(filename -> file_name); free(filename); return search_directory(inode_base, current -> inode, next); } } cur_index_serviced += current -> rec_len; if (cur_index_serviced < current_inode->i_size && cur_index_serviced % 1024 == 0){ cur_inode_index++; current_block = get_block_from_inode(inode_base, inode_num, cur_inode_index); } } struct parsed_filename *current_filename = filename -> next, *prev = filename; free(prev -> file_name); free(prev); while(current_filename){ prev = current_filename; current_filename = current_filename -> next; free(prev -> file_name); free(prev); } struct basic_fileinfo null_file; null_file.inode = 0; null_file.type = '\0'; return null_file; }
struct basic_fileinfo find_file(char *path, char *inode_base){ struct basic_fileinfo file_info; file_info.type = '\0'; //default file_info.inode = 0; if(path[0] == '\0'){ return file_info; //perhaps an error goes here? } else if (path[0] == '/' && path[1] == '\0'){ file_info.type = 'd'; file_info.inode = 2; return file_info; } struct parsed_filename *directory_linked_list = parse_directory(path); if(!directory_linked_list){ return file_info; } return search_directory(inode_base, 2, directory_linked_list); }
static int search_directory(const char *subject, const char *const base, char fullpath[CHIRP_PATH_MAX], const char *pattern, int flags, struct link *l, time_t stoptime) { if(strlen(pattern) == 0) return 0; debug(D_DEBUG, "search_directory(subject = `%s', base = `%s', fullpath = `%s', pattern = `%s', flags = %d, ...)", subject, base, fullpath, pattern, flags); int access_flags = search_to_access(flags); int includeroot = flags & CHIRP_SEARCH_INCLUDEROOT; int metadata = flags & CHIRP_SEARCH_METADATA; int stopatfirst = flags & CHIRP_SEARCH_STOPATFIRST; int result = 0; struct chirp_dir *dirp = cfs->opendir(fullpath); char *current = fullpath + strlen(fullpath); /* point to end to current directory */ if(dirp) { errno = 0; struct chirp_dirent *entry; while((entry = cfs->readdir(dirp))) { char *name = entry->name; if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0 || strncmp(name, ".__", 3) == 0) continue; sprintf(current, "/%s", name); if(search_match_file(pattern, base)) { const char *matched; if(includeroot) { if(base - fullpath == 1 && fullpath[0] == '/') { matched = base; } else { matched = fullpath; } } else { matched = base; } result += 1; if(access_flags == F_OK || cfs->access(fullpath, access_flags) == 0) { if(metadata) { /* A match was found, but the matched file couldn't be statted. Generate a result and an error. */ if(entry->lstatus == -1) { link_putfstring(l, "0:%s::\n", stoptime, matched); // FIXME is this a bug? link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_STAT, matched); } else { BUFFER_STACK_ABORT(B, 4096) chirp_stat_encode(B, &entry->info); link_putfstring(l, "0:%s:%s:\n", stoptime, matched, buffer_tostring(B)); if(stopatfirst) return 1; } } else { link_putfstring(l, "0:%s::\n", stoptime, matched); if(stopatfirst) return 1; } } /* FIXME access failure */ } if(cfs_isdir(fullpath) && search_should_recurse(base, pattern)) { if(chirp_acl_check_dir(fullpath, subject, CHIRP_ACL_LIST)) { int n = search_directory(subject, base, fullpath, pattern, flags, l, stoptime); if(n > 0) { result += n; if(stopatfirst) return result; } } else { link_putfstring(l, "%d:%d:%s:\n", stoptime, EPERM, CHIRP_SEARCH_ERR_OPEN, fullpath); } } *current = '\0'; /* clear current entry */ errno = 0; } if(errno) link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_READ, fullpath); errno = 0; cfs->closedir(dirp); if(errno) link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_CLOSE, fullpath); } else { link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_OPEN, fullpath); } return result; }
/* * Open a file. */ static int ufs_open(const char *upath, struct open_file *f) { char *cp, *ncp; int c; ino_t inumber, parent_inumber; struct file *fp; struct fs *fs; int rc; size_t buf_size; int nlinks = 0; char namebuf[MAXPATHLEN+1]; char *buf = NULL; char *path = NULL; /* allocate file system specific data structure */ fp = malloc(sizeof(struct file)); bzero(fp, sizeof(struct file)); f->f_fsdata = (void *)fp; /* allocate space and read super block */ fs = malloc(SBSIZE); fp->f_fs = fs; twiddle(); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, SBOFF / DEV_BSIZE, SBSIZE, (char *)fs, &buf_size); if (rc) goto out; if (buf_size != SBSIZE || fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || fs->fs_bsize < sizeof(struct fs)) { rc = EINVAL; goto out; } #ifdef COMPAT_UFS ffs_oldfscompat(fs); #endif /* * Calculate indirect block levels. */ { int omult; int mult; int level; omult = 0; mult = 1; for (level = 0; level < NIADDR; level++) { mult *= NINDIR(fs); if (mult < omult) mult = 0x7FFFFFFF; fp->f_nindir[level] = mult; omult = mult; } } inumber = ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; cp = path = strdup(upath); if (path == NULL) { rc = ENOMEM; goto out; } while (*cp) { /* * Remove extra separators */ while (*cp == '/') cp++; if (*cp == '\0') break; /* * Check that current node is a directory. */ if ((fp->f_di.di_mode & IFMT) != IFDIR) { rc = ENOTDIR; goto out; } /* * Get next component of path name. */ { int len = 0; ncp = cp; while ((c = *cp) != '\0' && c != '/') { if (++len > MAXNAMLEN) { rc = ENOENT; goto out; } cp++; } *cp = '\0'; } /* * Look up component in current directory. * Save directory inumber in case we find a * symbolic link. */ parent_inumber = inumber; rc = search_directory(ncp, f, &inumber); *cp = c; if (rc) goto out; /* * Open next component. */ if ((rc = read_inode(inumber, f)) != 0) goto out; /* * Check for symbolic link. */ if ((fp->f_di.di_mode & IFMT) == IFLNK) { int link_len = fp->f_di.di_size; int len; len = strlen(cp); if (link_len + len > MAXPATHLEN || ++nlinks > MAXSYMLINKS) { rc = ENOENT; goto out; } bcopy(cp, &namebuf[link_len], len + 1); if (link_len < fs->fs_maxsymlinklen) { bcopy(fp->f_di.di_shortlink, namebuf, (unsigned) link_len); } else { /* * Read file for symbolic link */ size_t buf_size; daddr_t disk_block; struct fs *fs = fp->f_fs; if (!buf) buf = malloc(fs->fs_bsize); rc = block_map(f, (daddr_t)0, &disk_block); if (rc) goto out; twiddle(); rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsbtodb(fs, disk_block), fs->fs_bsize, buf, &buf_size); if (rc) goto out; bcopy((char *)buf, namebuf, (unsigned)link_len); } /* * If relative pathname, restart at parent directory. * If absolute pathname, restart at root. */ cp = namebuf; if (*cp != '/') inumber = parent_inumber; else inumber = (ino_t)ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; } } /* * Found terminal component. */ fp->f_seekp = 0; rc = 0; out: if (buf) free(buf); if (path) free(path); if (rc) { f->f_fsdata = NULL; if (fp->f_buf) free(fp->f_buf); free(fp->f_fs); free(fp); } return (rc); }
static UINT search_dr( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) { static const WCHAR query[] = { 's','e','l','e','c','t',' ','*',' ', 'f','r','o','m',' ', 'D','r','L','o','c','a','t','o','r',' ', 'w','h','e','r','e',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; LPWSTR parent = NULL; LPCWSTR parentName; WCHAR path[MAX_PATH]; WCHAR expanded[MAX_PATH]; MSIRECORD *row; int depth; DWORD sz, attr; UINT rc; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord( package->db, query, sig->Name ); if (!row) { TRACE("failed to query DrLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } /* check whether parent is set */ parentName = MSI_RecordGetString(row, 2); if (parentName) { MSISIGNATURE parentSig; search_sig_name( package, parentName, &parentSig, &parent ); free_signature( &parentSig ); if (!parent) { msiobj_release(&row->hdr); return ERROR_SUCCESS; } } sz = MAX_PATH; MSI_RecordGetStringW(row, 3, path, &sz); if (MSI_RecordIsNull(row,4)) depth = 0; else depth = MSI_RecordGetInteger(row,4); if (sz) expand_any_path( package, path, expanded, MAX_PATH ); else strcpyW(expanded, path); if (parent) { attr = msi_get_file_attributes( package, parent ); if (attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY)) { PathRemoveFileSpecW(parent); PathAddBackslashW(parent); } strcpyW(path, parent); strcatW(path, expanded); } else if (sz) strcpyW(path, expanded); PathAddBackslashW(path); rc = search_directory( package, sig, path, depth, appValue ); msi_free(parent); msiobj_release(&row->hdr); TRACE("returning %d\n", rc); return rc; }
static UINT search_reg( MSIPACKAGE *package, WCHAR **appValue, MSISIGNATURE *sig ) { static const WCHAR query[] = { 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ', 'R','e','g','L','o','c','a','t','o','r',' ','W','H','E','R','E',' ', 'S','i','g','n','a','t','u','r','e','_',' ','=',' ', '\'','%','s','\'',0}; const WCHAR *keyPath, *valueName; WCHAR *deformatted = NULL, *ptr = NULL, *end; int root, type; REGSAM access = KEY_READ; HKEY rootKey, key = NULL; DWORD sz = 0, regType; LPBYTE value = NULL; MSIRECORD *row; UINT rc; TRACE("%s\n", debugstr_w(sig->Name)); *appValue = NULL; row = MSI_QueryGetRecord( package->db, query, sig->Name ); if (!row) { TRACE("failed to query RegLocator for %s\n", debugstr_w(sig->Name)); return ERROR_SUCCESS; } root = MSI_RecordGetInteger(row, 2); keyPath = MSI_RecordGetString(row, 3); valueName = MSI_RecordGetString(row, 4); type = MSI_RecordGetInteger(row, 5); deformat_string(package, keyPath, &deformatted); switch (root) { case msidbRegistryRootClassesRoot: rootKey = HKEY_CLASSES_ROOT; break; case msidbRegistryRootCurrentUser: rootKey = HKEY_CURRENT_USER; break; case msidbRegistryRootLocalMachine: rootKey = HKEY_LOCAL_MACHINE; if (type & msidbLocatorType64bit) access |= KEY_WOW64_64KEY; else access |= KEY_WOW64_32KEY; break; case msidbRegistryRootUsers: rootKey = HKEY_USERS; break; default: WARN("Unknown root key %d\n", root); goto end; } rc = RegOpenKeyExW( rootKey, deformatted, 0, access, &key ); if (rc) { TRACE("RegOpenKeyExW returned %d\n", rc); goto end; } msi_free(deformatted); deformat_string(package, valueName, &deformatted); rc = RegQueryValueExW(key, deformatted, NULL, NULL, NULL, &sz); if (rc) { TRACE("RegQueryValueExW returned %d\n", rc); goto end; } /* FIXME: sanity-check sz before allocating (is there an upper-limit * on the value of a property?) */ value = msi_alloc( sz ); rc = RegQueryValueExW(key, deformatted, NULL, ®Type, value, &sz); if (rc) { TRACE("RegQueryValueExW returned %d\n", rc); goto end; } /* bail out if the registry key is empty */ if (sz == 0) goto end; /* expand if needed */ if (regType == REG_EXPAND_SZ) { sz = ExpandEnvironmentStringsW((LPCWSTR)value, NULL, 0); if (sz) { LPWSTR buf = msi_alloc(sz * sizeof(WCHAR)); ExpandEnvironmentStringsW((LPCWSTR)value, buf, sz); msi_free(value); value = (LPBYTE)buf; } } if ((regType == REG_SZ || regType == REG_EXPAND_SZ) && (ptr = strchrW((LPWSTR)value, '"')) && (end = strchrW(++ptr, '"'))) *end = '\0'; else ptr = (LPWSTR)value; switch (type & 0x0f) { case msidbLocatorTypeDirectory: search_directory( package, sig, ptr, 0, appValue ); break; case msidbLocatorTypeFileName: *appValue = search_file( package, ptr, sig ); break; case msidbLocatorTypeRawValue: convert_reg_value( regType, value, sz, appValue ); break; default: FIXME("unimplemented for type %d (key path %s, value %s)\n", type, debugstr_w(keyPath), debugstr_w(valueName)); } end: msi_free( value ); RegCloseKey( key ); msi_free( deformatted ); msiobj_release(&row->hdr); return ERROR_SUCCESS; }
iNode * parser_path(char * path, iNode * posible_inode){ int path_status = OK_STATUS; int path_parsing = PARSING_PATH; int i=0; int j=0; int last = 0; int status; iNode * old_current = posible_inode; iNode * temp_inode; char buffer[MAX_COMMAND_LENGHT]; int index = 0; /* Veo que tengo al empezar */ if ( path[i] == '/' ){ posible_inode = superblock->root; status = BARRA; } else if ( path[i] == '.' ) { status = PUNTO; } else { status = CARACTER; buffer[j++] = path [i]; } i++; /* Voy Switecheando el status y armando los nombres hasta que termine de parsear u obtenga un path incorrecto */ while( path_parsing != WRONG_PATH && path_parsing != END_PATH ){ if ( path[i] == '\0' ) { path_parsing = END_PATH; } if( status == BARRA ) { if ( path[i] == '/' ) { path_status = WRONG_PATH; }else if ( path[i] == '.' ) { status = PUNTO; }else { status = CARACTER; buffer[j++] = path[i]; } } else if (status == PUNTO ) { if( path[i] == '\0'){ path_status = OK_STATUS; path_parsing = END_PATH; } else if ( path[i] == '/') { status = BARRA; } else if ( path[i] == '.' ) { if ( path[i+1] != '/' && path[i+1] != '\0') { if ( i > 2 && path[i-2] != '/') path_status = WRONG_PATH; } else { posible_inode = search_directory("..",posible_inode); i++; } status = PUNTO; }else { status = CARACTER; buffer[j++] = '.'; buffer[j++] = path[i]; } } else if ( status == CARACTER ) { if ( path[i] == '\0') { path_parsing = END_PATH; path_status = OK_STATUS; buffer[j] = '\0'; if( ( temp_inode = search_directory(buffer, posible_inode) ) != NULL){ posible_inode = temp_inode; j=0; }else { path_status = WRONG_PATH; } } if ( path[i] == '/') { status = BARRA; buffer[j] = '\0'; if( ( temp_inode = search_directory(buffer, posible_inode) ) != NULL){ posible_inode = temp_inode; j=0; }else { path_status = WRONG_PATH; } } if ( path[i] == '.' ) { status = PUNTO; buffer[j++] = path[i]; }else { status = CARACTER; buffer[j++] = path[i]; } i++; } } if ( path_status == WRONG_PATH ){ return NULL; } return posible_inode; }
/* * Open a file. */ static int ext2fs_open(const char *upath, struct open_file *f) { struct file *fp; struct ext2fs *fs; size_t buf_size; ino_t inumber, parent_inumber; int i, len, groups, bg_per_blk, blkgrps, mult; int nlinks = 0; int error = 0; char *cp, *ncp, *path = NULL, *buf = NULL; char namebuf[MAXPATHLEN+1]; char c; /* allocate file system specific data structure */ fp = malloc(sizeof(struct file)); if (fp == NULL) return (ENOMEM); bzero(fp, sizeof(struct file)); f->f_fsdata = (void *)fp; /* allocate space and read super block */ fs = (struct ext2fs *)malloc(sizeof(*fs)); fp->f_fs = fs; twiddle(); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, EXT2_SBLOCK, EXT2_SBSIZE, (char *)fs, &buf_size); if (error) goto out; if (buf_size != EXT2_SBSIZE || fs->fs_magic != EXT2_MAGIC) { error = EINVAL; goto out; } /* * compute in-core values for the superblock */ fs->fs_bshift = EXT2_MINBSHIFT + fs->fs_fd.fd_bsize; fs->fs_bsize = 1 << fs->fs_bshift; fs->fs_bmask = fs->fs_bsize - 1; fs->fs_fshift = EXT2_MINFSHIFT + fs->fs_fd.fd_fsize; fs->fs_fsize = 1 << fs->fs_fshift; fs->fs_fmask = fs->fs_fsize - 1; if (fs->fs_revision == EXT2_REV0) { fs->fs_isize = EXT2_R0_ISIZE; fs->fs_firstino = EXT2_R0_FIRSTINO; } else { fs->fs_isize = fs->fs_fd.fd_isize; fs->fs_firstino = fs->fs_fd.fd_firstino; } fs->fs_imask = fs->fs_isize - 1; fs->fs_ipb = fs->fs_bsize / fs->fs_isize; fs->fs_fsbtodb = (fs->fs_bsize / DEV_BSIZE) - 1; /* * we have to load in the "group descriptors" here */ groups = howmany(fs->fs_blocks - fs->fs_firstblk, fs->fs_bpg); bg_per_blk = fs->fs_bsize / sizeof(struct ext2blkgrp); blkgrps = howmany(groups, bg_per_blk); len = blkgrps * fs->fs_bsize; fp->f_bg = malloc(len); twiddle(); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, EXT2_SBLOCK + EXT2_SBSIZE / DEV_BSIZE, len, (char *)fp->f_bg, &buf_size); if (error) goto out; /* * XXX * validation of values? (blocksize, descriptors, etc?) */ /* * Calculate indirect block levels. */ mult = 1; for (i = 0; i < NIADDR; i++) { mult *= nindir(fs); fp->f_nindir[i] = mult; } inumber = EXT2_ROOTINO; if ((error = read_inode(inumber, f)) != 0) goto out; path = strdup(upath); if (path == NULL) { error = ENOMEM; goto out; } cp = path; while (*cp) { /* * Remove extra separators */ while (*cp == '/') cp++; if (*cp == '\0') break; /* * Check that current node is a directory. */ if (! S_ISDIR(fp->f_di.di_mode)) { error = ENOTDIR; goto out; } /* * Get next component of path name. */ len = 0; ncp = cp; while ((c = *cp) != '\0' && c != '/') { if (++len > EXT2_MAXNAMLEN) { error = ENOENT; goto out; } cp++; } *cp = '\0'; /* * Look up component in current directory. * Save directory inumber in case we find a * symbolic link. */ parent_inumber = inumber; error = search_directory(ncp, f, &inumber); *cp = c; if (error) goto out; /* * Open next component. */ if ((error = read_inode(inumber, f)) != 0) goto out; /* * Check for symbolic link. */ if (S_ISLNK(fp->f_di.di_mode)) { int link_len = fp->f_di.di_size; int len; len = strlen(cp); if (link_len + len > MAXPATHLEN || ++nlinks > MAXSYMLINKS) { error = ENOENT; goto out; } bcopy(cp, &namebuf[link_len], len + 1); if (fp->f_di.di_nblk == 0) { bcopy(fp->f_di.di_shortlink, namebuf, link_len); } else { /* * Read file for symbolic link */ struct ext2fs *fs = fp->f_fs; daddr_t disk_block; size_t buf_size; if (! buf) buf = malloc(fs->fs_bsize); error = block_map(f, (daddr_t)0, &disk_block); if (error) goto out; twiddle(); error = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, fsb_to_db(fs, disk_block), fs->fs_bsize, buf, &buf_size); if (error) goto out; bcopy((char *)buf, namebuf, link_len); } /* * If relative pathname, restart at parent directory. * If absolute pathname, restart at root. */ cp = namebuf; if (*cp != '/') inumber = parent_inumber; else inumber = (ino_t)EXT2_ROOTINO; if ((error = read_inode(inumber, f)) != 0) goto out; } } /* * Found terminal component. */ error = 0; out: if (buf) free(buf); if (path) free(path); if (error) { f->f_fsdata = NULL; if (fp->f_buf) free(fp->f_buf); free(fp->f_fs); free(fp); } return (error); }
/* * Open a file. */ __compactcall int ext2fs_open(const char *path, struct open_file *f) { #ifndef LIBSA_FS_SINGLECOMPONENT const char *cp, *ncp; int c; #endif ino32_t inumber; struct file *fp; struct m_ext2fs *fs; int rc; #ifndef LIBSA_NO_FS_SYMLINK ino32_t parent_inumber; int nlinks = 0; char namebuf[MAXPATHLEN+1]; char *buf; #endif /* allocate file system specific data structure */ fp = alloc(sizeof(struct file)); memset(fp, 0, sizeof(struct file)); f->f_fsdata = (void *)fp; /* allocate space and read super block */ fs = alloc(sizeof(*fs)); memset(fs, 0, sizeof(*fs)); fp->f_fs = fs; twiddle(); rc = read_sblock(f, fs); if (rc) goto out; #ifdef EXT2FS_DEBUG dump_sblock(fs); #endif /* alloc a block sized buffer used for all fs transfers */ fp->f_buf = alloc(fs->e2fs_bsize); /* read group descriptor blocks */ fs->e2fs_gd = alloc(sizeof(struct ext2_gd) * fs->e2fs_ncg); rc = read_gdblock(f, fs); if (rc) goto out; /* * Calculate indirect block levels. */ { indp_t mult; int ln2; /* * We note that the number of indirect blocks is always * a power of 2. This lets us use shifts and masks instead * of divide and remainder and avoinds pulling in the * 64bit division routine into the boot code. */ mult = EXT2_NINDIR(fs); #ifdef DEBUG if (!powerof2(mult)) { /* Hummm was't a power of 2 */ rc = EINVAL; goto out; } #endif for (ln2 = 0; mult != 1; ln2++) mult >>= 1; fp->f_nishift = ln2; } inumber = EXT2_ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; #ifndef LIBSA_FS_SINGLECOMPONENT cp = path; while (*cp) { /* * Remove extra separators */ while (*cp == '/') cp++; if (*cp == '\0') break; /* * Check that current node is a directory. */ if ((fp->f_di.e2di_mode & EXT2_IFMT) != EXT2_IFDIR) { rc = ENOTDIR; goto out; } /* * Get next component of path name. */ ncp = cp; while ((c = *cp) != '\0' && c != '/') cp++; /* * Look up component in current directory. * Save directory inumber in case we find a * symbolic link. */ #ifndef LIBSA_NO_FS_SYMLINK parent_inumber = inumber; #endif rc = search_directory(ncp, cp - ncp, f, &inumber); if (rc) goto out; /* * Open next component. */ if ((rc = read_inode(inumber, f)) != 0) goto out; #ifndef LIBSA_NO_FS_SYMLINK /* * Check for symbolic link. */ if ((fp->f_di.e2di_mode & EXT2_IFMT) == EXT2_IFLNK) { /* XXX should handle LARGEFILE */ int link_len = fp->f_di.e2di_size; int len; len = strlen(cp); if (link_len + len > MAXPATHLEN || ++nlinks > MAXSYMLINKS) { rc = ENOENT; goto out; } memmove(&namebuf[link_len], cp, len + 1); if (link_len < EXT2_MAXSYMLINKLEN) { memcpy(namebuf, fp->f_di.e2di_blocks, link_len); } else { /* * Read file for symbolic link */ size_t buf_size; indp_t disk_block; buf = fp->f_buf; rc = block_map(f, (indp_t)0, &disk_block); if (rc) goto out; twiddle(); rc = DEV_STRATEGY(f->f_dev)(f->f_devdata, F_READ, FSBTODB(fs, disk_block), fs->e2fs_bsize, buf, &buf_size); if (rc) goto out; memcpy(namebuf, buf, link_len); } /* * If relative pathname, restart at parent directory. * If absolute pathname, restart at root. */ cp = namebuf; if (*cp != '/') inumber = parent_inumber; else inumber = (ino32_t)EXT2_ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; } #endif /* !LIBSA_NO_FS_SYMLINK */ } /* * Found terminal component. */ rc = 0; #else /* !LIBSA_FS_SINGLECOMPONENT */ /* look up component in the current (root) directory */ rc = search_directory(path, strlen(path), f, &inumber); if (rc) goto out; /* open it */ rc = read_inode(inumber, f); #endif /* !LIBSA_FS_SINGLECOMPONENT */ fp->f_seekp = 0; /* reset seek pointer */ out: if (rc) ext2fs_close(f); else fsmod = "ext2fs"; return rc; }
/* * Open a file. */ __compactcall int ufs_open(const char *path, struct open_file *f) { #ifndef LIBSA_FS_SINGLECOMPONENT const char *cp, *ncp; int c; #endif ino32_t inumber; struct file *fp; struct fs *fs; int rc; #ifndef LIBSA_NO_FS_SYMLINK ino32_t parent_inumber; int nlinks = 0; char namebuf[MAXPATHLEN+1]; char *buf; #endif /* allocate file system specific data structure */ fp = alloc(sizeof(struct file)); memset(fp, 0, sizeof(struct file)); f->f_fsdata = (void *)fp; /* allocate space and read super block */ fs = alloc(SBLOCKSIZE); fp->f_fs = fs; twiddle(); #ifdef LIBSA_FFSv2 rc = ffs_find_superblock(f, fs); if (rc) goto out; #else { size_t buf_size; rc = DEV_STRATEGY(f->f_dev)(f->f_devdata, F_READ, SBLOCKOFFSET / DEV_BSIZE, SBLOCKSIZE, fs, &buf_size); if (rc) goto out; if (buf_size != SBLOCKSIZE || #ifdef LIBSA_FFS fs->lfs_version != REQUIRED_LFS_VERSION || #endif fs->fs_magic != FS_MAGIC) { rc = EINVAL; goto out; } } #if defined(LIBSA_LFS) && REQUIRED_LFS_VERSION == 2 /* * XXX We should check the second superblock and use the eldest * of the two. See comments near the top of lfs_mountfs() * in sys/ufs/lfs/lfs_vfsops.c. * This may need a LIBSA_LFS_SMALL check as well. */ #endif #endif #ifdef LIBSA_FFSv1 ffs_oldfscompat(fs); #endif if (fs->fs_bsize > MAXBSIZE || (size_t)fs->fs_bsize < sizeof(struct fs)) { rc = EINVAL; goto out; } /* * Calculate indirect block levels. */ { indp_t mult; int ln2; /* * We note that the number of indirect blocks is always * a power of 2. This lets us use shifts and masks instead * of divide and remainder and avoinds pulling in the * 64bit division routine into the boot code. */ mult = UFS_NINDIR(fs); #ifdef DEBUG if (mult & (mult - 1)) { /* Hummm was't a power of 2 */ rc = EINVAL; goto out; } #endif for (ln2 = 0; mult != 1; ln2++) mult >>= 1; fp->f_nishift = ln2; } /* alloc a block sized buffer used for all fs transfers */ fp->f_buf = alloc(fs->fs_bsize); inumber = UFS_ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; #ifndef LIBSA_FS_SINGLECOMPONENT cp = path; while (*cp) { /* * Remove extra separators */ while (*cp == '/') cp++; if (*cp == '\0') break; /* * Check that current node is a directory. */ if ((fp->f_di.di_mode & IFMT) != IFDIR) { rc = ENOTDIR; goto out; } /* * Get next component of path name. */ ncp = cp; while ((c = *cp) != '\0' && c != '/') cp++; /* * Look up component in current directory. * Save directory inumber in case we find a * symbolic link. */ #ifndef LIBSA_NO_FS_SYMLINK parent_inumber = inumber; #endif rc = search_directory(ncp, cp - ncp, f, &inumber); if (rc) goto out; /* * Open next component. */ if ((rc = read_inode(inumber, f)) != 0) goto out; #ifndef LIBSA_NO_FS_SYMLINK /* * Check for symbolic link. */ if ((fp->f_di.di_mode & IFMT) == IFLNK) { int link_len = fp->f_di.di_size; int len; len = strlen(cp); if (link_len + len > MAXPATHLEN || ++nlinks > MAXSYMLINKS) { rc = ENOENT; goto out; } memmove(&namebuf[link_len], cp, len + 1); if (link_len < fs->fs_maxsymlinklen) { memcpy(namebuf, fp->f_di.di_db, link_len); } else { /* * Read file for symbolic link */ size_t buf_size; indp_t disk_block; buf = fp->f_buf; rc = block_map(f, (indp_t)0, &disk_block); if (rc) goto out; twiddle(); rc = DEV_STRATEGY(f->f_dev)(f->f_devdata, F_READ, FSBTODB(fs, disk_block), fs->fs_bsize, buf, &buf_size); if (rc) goto out; memcpy(namebuf, buf, link_len); } /* * If relative pathname, restart at parent directory. * If absolute pathname, restart at root. */ cp = namebuf; if (*cp != '/') inumber = parent_inumber; else inumber = (ino32_t)UFS_ROOTINO; if ((rc = read_inode(inumber, f)) != 0) goto out; } #endif /* !LIBSA_NO_FS_SYMLINK */ } /* * Found terminal component. */ rc = 0; #else /* !LIBSA_FS_SINGLECOMPONENT */ /* look up component in the current (root) directory */ rc = search_directory(path, strlen(path), f, &inumber); if (rc) goto out; /* open it */ rc = read_inode(inumber, f); #endif /* !LIBSA_FS_SINGLECOMPONENT */ fp->f_seekp = 0; /* reset seek pointer */ out: if (rc) ufs_close(f); #ifdef FSMOD /* Only defined for lfs */ else fsmod = FSMOD; #endif return rc; }
static int search_directory(const char *subject, const char * const base, char *fullpath, const char *pattern, int flags, struct link *l, time_t stoptime) { if(strlen(pattern) == 0) return 0; debug(D_DEBUG, "search_directory(subject = `%s', base = `%s', fullpath = `%s', pattern = `%s', flags = %d, ...)", subject, base, fullpath, pattern, flags); int access_flags = search_to_access(flags); int includeroot = flags & CHIRP_SEARCH_INCLUDEROOT; int metadata = flags & CHIRP_SEARCH_METADATA; int stopatfirst = flags & CHIRP_SEARCH_STOPATFIRST; int result = 0; void *dirp = chirp_fs_local_opendir(fullpath); char *current = fullpath + strlen(fullpath); /* point to end to current directory */ if(dirp) { errno = 0; struct chirp_dirent *entry; while((entry = chirp_fs_local_readdir(dirp))) { char *name = entry->name; if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0 || strncmp(name, ".__", 3) == 0) continue; sprintf(current, "/%s", name); if(search_match_file(pattern, base)) { const char *matched = includeroot ? fullpath+strlen(chirp_root_path) : base; /* add strlen(chirp_root_path) to strip out */ result += 1; if (access_flags == F_OK || chirp_fs_local_access(fullpath, access_flags) == 0) { if(metadata) { /* A match was found, but the matched file couldn't be statted. Generate a result and an error. */ struct chirp_stat buf; if((chirp_fs_local_stat(fullpath, &buf)) == -1) { link_putfstring(l, "0:%s::\n", stoptime, matched); // FIXME is this a bug? link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_STAT, matched); } else { link_putfstring(l, "0:%s:%s:\n", stoptime, matched, chirp_stat_string(&buf)); if(stopatfirst) return 1; } } else { link_putfstring(l, "0:%s::\n", stoptime, matched); if(stopatfirst) return 1; } } /* FIXME access failure */ } if(cfs_isdir(fullpath) && search_should_recurse(base, pattern)) { if(chirp_acl_check_dir(fullpath, subject, CHIRP_ACL_LIST)) { int n = search_directory(subject, base, fullpath, pattern, flags, l, stoptime); if(n > 0) { result += n; if(stopatfirst) return result; } } else { link_putfstring(l, "%d:%d:%s:\n", stoptime, EPERM, CHIRP_SEARCH_ERR_OPEN, fullpath); } } *current = '\0'; /* clear current entry */ errno = 0; } if(errno) link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_READ, fullpath); errno = 0; chirp_alloc_closedir(dirp); if(errno) link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_CLOSE, fullpath); } else { link_putfstring(l, "%d:%d:%s:\n", stoptime, errno, CHIRP_SEARCH_ERR_OPEN, fullpath); } return result; }