Ejemplo n.º 1
0
int dfs_romfs_read(struct dfs_fd *file, void *buf, size_t count)
{
    rt_size_t length;
    struct romfs_dirent *dirent;

    dirent = (struct romfs_dirent *)file->data;
    RT_ASSERT(dirent != NULL);

    if (check_dirent(dirent) != 0)
    {
        return -EIO;
    }

    if (count < file->size - file->pos)
        length = count;
    else
        length = file->size - file->pos;

    if (length > 0)
        memcpy(buf, &(dirent->data[file->pos]), length);

    /* update file current position */
    file->pos += length;

    return length;
}
Ejemplo n.º 2
0
int dfs_romfs_getdents(struct dfs_fd *file, struct dirent *dirp, uint32_t count)
{
    rt_size_t index;
    const char *name;
    struct dirent *d;
    struct romfs_dirent *dirent, *sub_dirent;

    dirent = (struct romfs_dirent *)file->data;
    if (check_dirent(dirent) != 0)
        return -EIO;
    RT_ASSERT(dirent->type == ROMFS_DIRENT_DIR);

    /* enter directory */
    dirent = (struct romfs_dirent *)dirent->data;

    /* make integer count */
    count = (count / sizeof(struct dirent));
    if (count == 0)
        return -EINVAL;

    index = 0;
    for (index = 0; index < count && file->pos < file->size; index ++)
    {
        d = dirp + index;

        sub_dirent = &dirent[file->pos];
        name = sub_dirent->name;

        /* fill dirent */
        if (sub_dirent->type == ROMFS_DIRENT_DIR)
            d->d_type = DT_DIR;
        else
            d->d_type = DT_REG;

        d->d_namlen = rt_strlen(name);
        d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
        rt_strncpy(d->d_name, name, rt_strlen(name) + 1);

        /* move to next position */
        ++ file->pos;
    }

    return index * sizeof(struct dirent);
}
Ejemplo n.º 3
0
int dfs_romfs_open(struct dfs_fd *file)
{
    rt_size_t size;
    struct romfs_dirent *dirent;
    struct romfs_dirent *root_dirent;
    struct dfs_filesystem *fs;

    fs = (struct dfs_filesystem *)file->data;
    root_dirent = (struct romfs_dirent *)fs->data;

    if (check_dirent(root_dirent) != 0)
        return -EIO;

    if (file->flags & (O_CREAT | O_WRONLY | O_APPEND | O_TRUNC | O_RDWR))
        return -EINVAL;

    dirent = dfs_romfs_lookup(root_dirent, file->path, &size);
    if (dirent == NULL)
        return -ENOENT;

    /* entry is a directory file type */
    if (dirent->type == ROMFS_DIRENT_DIR)
    {
        if (!(file->flags & O_DIRECTORY))
            return -ENOENT;
    }
    else
    {
        /* entry is a file, but open it as a directory */
        if (file->flags & O_DIRECTORY)
            return -ENOENT;
    }

    file->data = dirent;
    file->size = size;
    file->pos = 0;

    return RT_EOK;
}
Ejemplo n.º 4
0
struct romfs_dirent *dfs_romfs_lookup(struct romfs_dirent *root_dirent, const char *path, rt_size_t *size)
{
    rt_size_t index, found;
    const char *subpath, *subpath_end;
    struct romfs_dirent *dirent;
    rt_size_t dirent_size;

    /* Check the root_dirent. */
    if (check_dirent(root_dirent) != 0)
        return NULL;

    if (path[0] == '/' && path[1] == '\0')
    {
        *size = root_dirent->size;
        return root_dirent;
    }

    /* goto root directy entries */
    dirent = (struct romfs_dirent *)root_dirent->data;
    dirent_size = root_dirent->size;

    /* get the end position of this subpath */
    subpath_end = path;
    /* skip /// */
    while (*subpath_end && *subpath_end == '/')
        subpath_end ++;
    subpath = subpath_end;
    while ((*subpath_end != '/') && *subpath_end)
        subpath_end ++;

    while (dirent != NULL)
    {
        found = 0;

        /* search in folder */
        for (index = 0; index < dirent_size; index ++)
        {
            if (check_dirent(&dirent[index]) != 0)
                return NULL;
            if (rt_strlen(dirent[index].name) == (subpath_end - subpath) &&
                    rt_strncmp(dirent[index].name, subpath, (subpath_end - subpath)) == 0)
            {
                dirent_size = dirent[index].size;

                /* skip /// */
                while (*subpath_end && *subpath_end == '/')
                    subpath_end ++;
                subpath = subpath_end;
                while ((*subpath_end != '/') && *subpath_end)
                    subpath_end ++;

                if (!(*subpath))
                {
                    *size = dirent_size;
                    return &dirent[index];
                }

                if (dirent[index].type == ROMFS_DIRENT_DIR)
                {
                    /* enter directory */
                    dirent = (struct romfs_dirent*)dirent[index].data;
                    found = 1;
                    break;
                }
                else
                {
                    /* return file dirent */
                    if (subpath != NULL)
                        break; /* not the end of path */

                    return &dirent[index];
                }
            }
        }

        if (!found)
            break; /* not found */
    }

    /* not found */
    return NULL;
}
Ejemplo n.º 5
0
static int catsearch(struct vol *vol,
                     struct dir *dir,  
                     int rmatches,
                     uint32_t *pos,
                     char *rbuf,
                     uint32_t *nrecs,
                     int *rsize,
                     int ext)
{
    static u_int32_t cur_pos;    /* Saved position index (ID) - used to remember "position" across FPCatSearch calls */
    static DIR *dirpos; 		 /* UNIX structure describing currently opened directory. */
    struct dir *currentdir;      /* struct dir of current directory */
	int cidx, r;
	struct dirent *entry;
	int result = AFP_OK;
	int ccr;
    struct path path;
	char *vpath = vol->v_path;
	char *rrbuf = rbuf;
    time_t start_time;
    int num_rounds = NUM_ROUNDS;
    int cwd = -1;
    int error;
    int unlen;

	if (*pos != 0 && *pos != cur_pos) {
		result = AFPERR_CATCHNG;
		goto catsearch_end;
	}

	/* FIXME: Category "offspring count ! */


	/* We need to initialize all mandatory structures/variables and change working directory appropriate... */
	if (*pos == 0) {
		clearstack();
		if (dirpos != NULL) {
			closedir(dirpos);
			dirpos = NULL;
		} 
		
		if (addstack(vpath, dir, -1) == -1) {
			result = AFPERR_MISC;
			goto catsearch_end;
		}
		/* FIXME: Sometimes DID is given by client ! (correct this one above !) */
	}

	/* Save current path */
    if ((cwd = open(".", O_RDONLY)) < 0) {
        result = AFPERR_MISC;
        goto catsearch_end;
    }
	
	/* So we are beginning... */
    start_time = time(NULL);

	while ((cidx = reducestack()) != -1) {
        if ((currentdir = dirlookup(vol, dstack[cidx].ds_did)) == NULL) {
            result = AFPERR_MISC;
            goto catsearch_end;
        }
        LOG(log_debug, logtype_afpd, "catsearch: current struct dir: \"%s\"", cfrombstr(currentdir->d_fullpath));

		error = movecwd(vol, currentdir);

		if (!error && dirpos == NULL)
			dirpos = opendir(".");

		if (dirpos == NULL)
			dirpos = opendir(bdata(currentdir->d_fullpath));

		if (error || dirpos == NULL) {
			switch (errno) {
			case EACCES:
				dstack[cidx].ds_checked = 1;
				continue;
			case EMFILE:
			case ENFILE:
			case ENOENT:
				result = AFPERR_NFILE;
				break;
			case ENOMEM:
			case ENOTDIR:
			default:
				result = AFPERR_MISC;
			} /* switch (errno) */
			goto catsearch_end;
		}

		
		while ((entry = readdir(dirpos)) != NULL) {
			(*pos)++;

			if (!check_dirent(vol, entry->d_name))
			   continue;

            LOG(log_debug, logtype_afpd, "catsearch(\"%s\"): dirent: \"%s\"",
                cfrombstr(currentdir->d_fullpath), entry->d_name);

			memset(&path, 0, sizeof(path));
			path.u_name = entry->d_name;
			if (of_stat(vol, &path) != 0) {
				switch (errno) {
				case EACCES:
				case ELOOP:
				case ENOENT:
					continue;
				case ENOTDIR:
				case EFAULT:
				case ENOMEM:
				case ENAMETOOLONG:
				default:
					result = AFPERR_MISC;
					goto catsearch_end;
				} 
			}
            switch (S_IFMT & path.st.st_mode) {
            case S_IFDIR:
				/* here we can short cut 
				   ie if in the same loop the parent dir wasn't in the cache
				   ALL dirsearch_byname will fail.
				*/
                unlen = strlen(path.u_name);
                path.d_dir = dircache_search_by_name(vol,
                                                     currentdir,
                                                     path.u_name,
                                                     unlen);
            	if (path.d_dir == NULL) {
                	/* path.m_name is set by adddir */
            	    if ((path.d_dir = dir_add(vol,
                                              currentdir,
                                              &path,
                                              unlen)) == NULL) {
						result = AFPERR_MISC;
						goto catsearch_end;
					}
                }
                path.m_name = cfrombstr(path.d_dir->d_m_name);
                	
				if (addstack(path.u_name, path.d_dir, cidx) == -1) {
					result = AFPERR_MISC;
					goto catsearch_end;
				} 
                break;
            case S_IFREG:
            	path.d_dir = currentdir;
                break;
            default:
                continue;
            }

			ccr = crit_check(vol, &path);

			/* bit 0 means that criteria has been met */
			if ((ccr & 1)) {
				r = rslt_add ( vol, &path, &rrbuf, ext);
				
				if (r == 0) {
					result = AFPERR_MISC;
					goto catsearch_end;
				} 
				*nrecs += r;
				/* Number of matches limit */
				if (--rmatches == 0) 
					goto catsearch_pause;
				/* Block size limit */
				if (rrbuf - rbuf >= 448)
					goto catsearch_pause;
			}
			/* MacOS 9 doesn't like servers executing commands longer than few seconds */
			if (--num_rounds <= 0) {
			    if (start_time != time(NULL)) {
					result=AFP_OK;
					goto catsearch_pause;
			    }
			    num_rounds = NUM_ROUNDS;
			}
		} /* while ((entry=readdir(dirpos)) != NULL) */
		closedir(dirpos);
		dirpos = NULL;
		dstack[cidx].ds_checked = 1;
	} /* while (current_idx = reducestack()) != -1) */

	/* We have finished traversing our tree. Return EOF here. */
	result = AFPERR_EOF;
	goto catsearch_end;

catsearch_pause:
	cur_pos = *pos; 
	save_cidx = cidx;

catsearch_end: /* Exiting catsearch: error condition */
	*rsize = rrbuf - rbuf;
    if (cwd != -1) {
        if ((fchdir(cwd)) != 0) {
            LOG(log_debug, logtype_afpd, "error chdiring back: %s", strerror(errno));        
        }
        close(cwd);
    }
	return result;
} /* catsearch() */