Exemplo n.º 1
0
void ManifestDtor(struct Manifest *manifest)
{
  int i;
  int j;

  if(manifest == NULL) return;

  /* channels */
  for(i = 0; i < manifest->channels->len; ++i)
  {
    struct ChannelDesc *channel = g_ptr_array_index(manifest->channels, i);

    /* sources */
    for(j = 0; j < channel->source->len; ++j)
    {
      struct File *file = g_ptr_array_index(channel->source, j);
      if(IS_FILE(file))
        g_free(file->name);
      g_free(file);
    }
    g_ptr_array_free(channel->source, TRUE);
    g_free(channel->alias);
    TagDtor(channel->tag);
    g_free(channel);
  }
  g_ptr_array_free(manifest->channels, TRUE);

  /* other */
  g_free(manifest->etag);
  TagDtor(manifest->mem_tag);
  g_free(manifest->name_server);
  g_free(manifest->program);
  g_free(manifest);
}
Exemplo n.º 2
0
CScriptFile* lua_tofile ( lua_State* luaVM, int iArgument )
{
    CElement* pElement = lua_toelement ( luaVM, iArgument );
    if ( pElement && IS_FILE ( pElement ) )
        return static_cast < CScriptFile* > ( pElement );
    else
        return NULL;
}
Exemplo n.º 3
0
int print_conflicts(struct hash *hash)
{
    int i;
    struct tree_node *t, *s;
    char *pkgname;

    for (i = 0; i < TBLSIZE; i++) {
        t = tree_first(hash->tbl[i]->root);

        while (t) {
            if (!IS_FILE(t->n->name) || IS_DIR(t->n)
                || tree_count(t->n->providedby) < 2) {
                t = tree_next(t);
                continue;
            }

            printf("%s: ", t->n->name);

            s = tree_first(t->n->providedby->root);

            while (s) {
                if (IS_PKG(s->n)) {
                    printf("%s", s->n->name);
                } else if (is_virtual_file(s->n->name)) {
                    pkgname = get_pkgname(s->n->name);
                    printf("%s", pkgname);
                    free(pkgname);
                } else {
                    fprintf(stderr, "bee-dep: print_conflicts: "
                            "could not get pkgname for \"%s\"\n",
                            s->n->name);
                    return 1;
                }

                s = tree_next(s);

                if (!s)
                    puts("");
                else
                    printf(" ");
            }

            t = tree_next(t);
        }
    }

    return 0;
}
Exemplo n.º 4
0
/** mkworld():
 *  Compiles the sources, and eventually builds with biblatex
 */
void mkworld() {
	//struct stat okbiblio;
	
	do_argv(2,LATEX_COMPILER,"main.tex");

	do_argv(2,BIBTEX_COMPILER,"main.aux");
		
	do_argv(2,LATEX_COMPILER,"main.tex");
	do_argv(2,LATEX_COMPILER,"main.tex");

	if (IS_FILE("main.idx")) {
		printf("\033[35mThere is main.idx...\033[0m\n");
		do_argv(2,MAKEINDEX_COMP,"main.idx");
		
	}

	do_argv(2,LATEX_COMPILER,"main.tex");	
}
Exemplo n.º 5
0
static int count_all_files(struct node *n)
{
    struct tree_node *t;
    int count;

    t     = tree_first(n->provide->root);
    count = 0;

    while (t) {
        if (IS_FILE(t->n->name))
            count++;

        count += list_all_files(t->n, 0);

        t = tree_next(t);
    }

    return count;
}
Exemplo n.º 6
0
int fs_getdents(int fd, char *buf, size_t n)
{
    unsigned int i, pos;
    struct inode_s *dir, *ino;
    struct dir_entry_s dentry;
    struct dirent *dent;
    struct file_s *flip;

    flip = get_file(fd);
    dir = flip->f_ino;

    if (!IS_DIR(dir->i_mode))
        return ERROR;

    i = 0;
    pos = flip->f_pos;
    while (n >= sizeof(struct dirent) + 1) {
        if (next_entry(dir, &pos, &dentry) == ERROR)
            break;
        ino = get_inode(dentry.num);
        dent = (struct dirent *) (buf + i);
        dent->d_ino = dentry.num; 
        dent->d_off = pos - sizeof(struct dir_entry_s);
        dent->d_reclen = mystrncpy(dent->d_name, dentry.name, MAX_NAME) + 
                         1 +                      /* add the \0 */
                         sizeof(ino_t) +          /* add the d_ino */
                         sizeof(off_t) +          /* add the d_off */
                         sizeof(unsigned short) + /* add the d_reclen */
                         1;                       /* add the d_type */
        /* add d_type */
        *(buf + i + dent->d_reclen - 1) = (IS_DIR(ino->i_mode) ? DT_DIR :
                                          IS_FILE(ino->i_mode) ? DT_REG :
                                          IS_CHAR(ino->i_mode) ? DT_CHR :
                                                                 DT_UNK);
        i += dent->d_reclen;
        n -= dent->d_reclen;
        release_inode(ino);
    }
    flip->f_pos = pos;

    return i;
}
Exemplo n.º 7
0
static int
fatfs_remove(vnode_t dvp, vnode_t vp, char *name)
{
    struct fatfsmount *fmp;
    struct fatfs_node np;
    struct fat_dirent *de;
    int error;

    if (*name == '\0')
        return ENOENT;

    fmp = dvp->v_mount->m_data;
    mutex_lock(&fmp->lock);

    error = fatfs_lookup_node(dvp, name, &np);
    if (error)
        goto out;
    de = &np.dirent;
    if (IS_DIR(de)) {
        error = EISDIR;
        goto out;
    }
    if (!IS_FILE(de)) {
        error = EPERM;
        goto out;
    }

    /* Remove clusters */
    error = fat_free_clusters(fmp, (de->cluster_hi << 16) | de->cluster);
    if (error)
        goto out;

    /* remove directory */
    de->name[0] = 0xe5;
    error = fatfs_put_node(fmp, &np);
out:
    mutex_unlock(&fmp->lock);
    return error;
}
Exemplo n.º 8
0
void search_removable(struct hash *hash, struct node *n,
                      struct tree *t, char *remove)
{
    struct tree_node *e;
    char *pkgname;

    e = tree_first(n->provide->root);

    while (e) {
        search_removable(hash, e->n, t, remove);
        e = tree_next(e);
    }

    if (IS_FILE(n->name) && tree_count(n->providedby) <= 1) {
        pkgname = get_pkgname(n->providedby->root->n->name);

        if (!strcmp(pkgname, remove))
            tree_insert(t, n);

        free(pkgname);
    }
}
Exemplo n.º 9
0
static int list_all_files(struct node *n, char print)
{
    struct tree_node *t;
    int count;

    t     = tree_first(n->provide->root);
    count = 0;

    while (t) {
        if (IS_FILE(t->n->name)) {
            count++;

            if (print)
                puts(t->n->name);
        }

        count += list_all_files(t->n, print);

        t = tree_next(t);
    }

    return count;
}
Exemplo n.º 10
0
int graph_insert_nodes(struct hash *hash, char *filename)
{
    FILE *file;
    register char *s, *p, *a;
    char type_flag, u;
    char line[LINE_MAX],
         prop[LINE_MAX],
         value[LINE_MAX],
         pkgname[NODENAME_MAX]  = {0},
         nodename[NODENAME_MAX] = {0};
    int l, line_cnt;
    struct node *n, *h, *v, *c;

    if ((file = fopen(filename, "r")) == NULL) {
        perror("bee-dep: graph_insert_nodes: fopen");
        return 1;
    }

    line_cnt = type_flag = u = 0;
    n        = NULL;

    while (fgets(line, LINE_MAX, file)) {
        line_cnt++;

        if (!line[0])
            continue;

        /* remove unnecessary characters */
        l = strlen(line);
        s = line;
        p = line + (l - 1) * sizeof(char);
        h = NULL;

        while (p - s && *p && IS_WHITESPACE(*p))
            *(p--) = 0;

        while (*s && (*s == ' ' || *s == '\t'))
            s++;

        l = p - s;

        if (l <= 0 || *s == '#')
            continue;

        /* read node name */
        if (*s == '[') {
            s++;

            if (*p != ']') {
                fprintf(stderr,
                        "bee-dep: %s: error at line %d: missing bracket\n",
                        filename, line_cnt);
                return 1;
            }

            *p = '\0';

            if (p - s == 0) {
                fprintf(stderr,
                        "bee-dep: %s: error at line %d: empty node name\n",
                        filename, line_cnt);
                return 1;
            }

            if (IS_FILE(s)) {
                if (!pkgname[0]) {
                    fprintf(stderr,
                            "bee-dep: %s: error at line %d: "
                            "dont know to which package"
                            "\"%s\" belongs to\n", filename, line_cnt, s);
                    return 1;
                }

                sprintf(nodename, "%s%s", pkgname, s);
            } else {
                sprintf(nodename, "%s", s);
            }

            c = node_new(nodename, UNKNOWN);
            n = hash_safe_insert(hash, c);
            if (c != n)
                node_free(c);

            type_flag = 0;
            continue;
        }

        /* read node properties */
        a = s;

        while (*a && *a != ' ' && *a != '\t' && *a != '=')
            a++;

        l = a - s;

        memset(prop, '\0', LINE_MAX);
        strncpy(prop, s, l * sizeof(char));

        while (*a && (*a == ' ' || *a == '\t' || *a == '='))
            a++;

        l = p - a + 1;

        if (!l) {
            fprintf(stderr,
                    "bee-dep: warning: %s: line %d: missing value "
                    "for property \"%s\"\n", filename, line_cnt, prop);
        }

        memset(value, '\0', LINE_MAX);
        strncpy(value, a, l * sizeof(char));

        if (strcasecmp(prop, TYPE) == 0) {
            if (type_flag) {
                fprintf(stderr,
                        "bee-dep: %s: error at line %d: "
                        "ambiguous type \"%s\"\n",
                        filename, line_cnt, value);
                return 1;
            }

            node_set_type(n, value);

            if (is_virtual_file(n->name))
                node_set_type(hash_search(hash, get_filename(n->name)),
                              value);

            if (strcasecmp(PACKAGE, value) == 0)
                sprintf(pkgname, "%s", n->name);

            type_flag = 1;
        } else if (strcasecmp(prop, PROVIDES) == 0) {
            c = node_new(value, UNKNOWN);
            h = hash_safe_insert(hash, c);

            if (c != h)
                node_free(c);

            if (IS_FILE(value)) {
                sprintf(nodename, "%s%s", pkgname, value);

                c = node_new(nodename, UNKNOWN);
                v = hash_safe_insert(hash, c);

                if (v != c)
                    node_free(c);

                add_provide(n, v);
                add_provide(v, h);
            } else {
                add_provide(n, h);
            }
        } else if (strcasecmp(prop, NEEDS) == 0) {
            c = node_new(value, UNKNOWN);
            h = hash_safe_insert(hash, c);

            if (c != h)
                node_free(c);

            add_need(n, h);
        }
    }

    if (fclose(file) == EOF) {
        perror("bee-dep: graph_insert_nodes: fclose");
        return 1;
    }

    if (line_cnt == 0) {
        fprintf(stderr, "bee-dep: error: file '%s' is empty\n", filename);
        return 1;
    }

    return 0;
}
Exemplo n.º 11
0
Arquivo: p-file.c Projeto: mbk/ren-c
*/	static REB_R File_Actor(struct Reb_Call *call_, REBSER *port, REBCNT action)
/*
**		Internal port handler for files.
**
***********************************************************************/
{
	REBVAL *spec;
	REBVAL *path;
	REBREQ *file = 0;
	REBCNT args = 0;
	REBCNT len;
	REBOOL opened = FALSE;	// had to be opened (shortcut case)

	//Print("FILE ACTION: %r", Get_Action_Word(action));

	Validate_Port(port, action);

	*D_OUT = *D_ARG(1);

	// Validate PORT fields:
	spec = BLK_SKIP(port, STD_PORT_SPEC);
	if (!IS_OBJECT(spec)) Trap1_DEAD_END(RE_INVALID_SPEC, spec);
	path = Obj_Value(spec, STD_PORT_SPEC_HEAD_REF);
	if (!path) Trap1_DEAD_END(RE_INVALID_SPEC, spec);

	if (IS_URL(path)) path = Obj_Value(spec, STD_PORT_SPEC_HEAD_PATH);
	else if (!IS_FILE(path)) Trap1_DEAD_END(RE_INVALID_SPEC, path);

	// Get or setup internal state data:
	file = (REBREQ*)Use_Port_State(port, RDI_FILE, sizeof(*file));

	switch (action) {

	case A_READ:
		args = Find_Refines(call_, ALL_READ_REFS);

		// Handle the READ %file shortcut case:
		if (!IS_OPEN(file)) {
			REBCNT nargs = AM_OPEN_READ;
			if (args & AM_READ_SEEK) nargs |= AM_OPEN_SEEK;
			Setup_File(file, nargs, path);
			Open_File_Port(port, file, path);
			opened = TRUE;
		}

		if (args & AM_READ_SEEK) Set_Seek(file, D_ARG(ARG_READ_INDEX));
		len = Set_Length(
			file, D_REF(ARG_READ_PART) ? VAL_INT64(D_ARG(ARG_READ_LENGTH)) : -1
		);
		Read_File_Port(D_OUT, port, file, path, args, len);

		if (opened) {
			OS_DO_DEVICE(file, RDC_CLOSE);
			Cleanup_File(file);
		}

		if (file->error) Trap_Port_DEAD_END(RE_READ_ERROR, port, file->error);
		break;

	case A_APPEND:
		if (!(IS_BINARY(D_ARG(2)) || IS_STRING(D_ARG(2)) || IS_BLOCK(D_ARG(2))))
			Trap1_DEAD_END(RE_INVALID_ARG, D_ARG(2));
		file->special.file.index = file->special.file.size;
		SET_FLAG(file->modes, RFM_RESEEK);

	case A_WRITE:
		args = Find_Refines(call_, ALL_WRITE_REFS);
		spec = D_ARG(2); // data (binary, string, or block)

		// Handle the READ %file shortcut case:
		if (!IS_OPEN(file)) {
			REBCNT nargs = AM_OPEN_WRITE;
			if (args & AM_WRITE_SEEK || args & AM_WRITE_APPEND) nargs |= AM_OPEN_SEEK;
			else nargs |= AM_OPEN_NEW;
			Setup_File(file, nargs, path);
			Open_File_Port(port, file, path);
			opened = TRUE;
		}
		else {
			if (!GET_FLAG(file->modes, RFM_WRITE)) Trap1_DEAD_END(RE_READ_ONLY, path);
		}

		// Setup for /append or /seek:
		if (args & AM_WRITE_APPEND) {
			file->special.file.index = -1; // append
			SET_FLAG(file->modes, RFM_RESEEK);
		}
		if (args & AM_WRITE_SEEK) Set_Seek(file, D_ARG(ARG_WRITE_INDEX));

		// Determine length. Clip /PART to size of string if needed.
		len = VAL_LEN(spec);
		if (args & AM_WRITE_PART) {
			REBCNT n = Int32s(D_ARG(ARG_WRITE_LENGTH), 0);
			if (n <= len) len = n;
		}

		Write_File_Port(file, spec, len, args);

		if (opened) {
			OS_DO_DEVICE(file, RDC_CLOSE);
			Cleanup_File(file);
		}

		if (file->error) Trap1_DEAD_END(RE_WRITE_ERROR, path);
		break;

	case A_OPEN:
		args = Find_Refines(call_, ALL_OPEN_REFS);
		// Default file modes if not specified:
		if (!(args & (AM_OPEN_READ | AM_OPEN_WRITE))) args |= (AM_OPEN_READ | AM_OPEN_WRITE);
		Setup_File(file, args, path);
		Open_File_Port(port, file, path); // !!! needs to change file modes to R/O if necessary
		break;

	case A_COPY:
		if (!IS_OPEN(file)) Trap1_DEAD_END(RE_NOT_OPEN, path); //!!!! wrong msg
		len = Set_Length(file, D_REF(2) ? VAL_INT64(D_ARG(3)) : -1);
		Read_File_Port(D_OUT, port, file, path, args, len);
		break;

	case A_OPENQ:
		if (IS_OPEN(file)) return R_TRUE;
		return R_FALSE;

	case A_CLOSE:
		if (IS_OPEN(file)) {
			OS_DO_DEVICE(file, RDC_CLOSE);
			Cleanup_File(file);
		}
		break;

	case A_DELETE:
		if (IS_OPEN(file)) Trap1_DEAD_END(RE_NO_DELETE, path);
		Setup_File(file, 0, path);
		if (OS_DO_DEVICE(file, RDC_DELETE) < 0 ) Trap1_DEAD_END(RE_NO_DELETE, path);
		break;

	case A_RENAME:
		if (IS_OPEN(file)) Trap1_DEAD_END(RE_NO_RENAME, path);
		else {
			REBSER *target;

			Setup_File(file, 0, path);

			// Convert file name to OS format:
			if (!(target = Value_To_OS_Path(D_ARG(2), TRUE)))
				Trap1_DEAD_END(RE_BAD_FILE_PATH, D_ARG(2));
			file->common.data = BIN_DATA(target);
			OS_DO_DEVICE(file, RDC_RENAME);
			Free_Series(target);
			if (file->error) Trap1_DEAD_END(RE_NO_RENAME, path);
		}
		break;

	case A_CREATE:
		// !!! should it leave file open???
		if (!IS_OPEN(file)) {
			Setup_File(file, AM_OPEN_WRITE | AM_OPEN_NEW, path);
			if (OS_DO_DEVICE(file, RDC_CREATE) < 0) Trap_Port_DEAD_END(RE_CANNOT_OPEN, port, file->error);
			OS_DO_DEVICE(file, RDC_CLOSE);
		}
		break;

	case A_QUERY:
		if (!IS_OPEN(file)) {
			Setup_File(file, 0, path);
			if (OS_DO_DEVICE(file, RDC_QUERY) < 0) return R_NONE;
		}
		Ret_Query_File(port, file, D_OUT);
		// !!! free file path?
		break;

	case A_MODIFY:
		Set_Mode_Value(file, Get_Mode_Id(D_ARG(2)), D_ARG(3));
		if (!IS_OPEN(file)) {
			Setup_File(file, 0, path);
			if (OS_DO_DEVICE(file, RDC_MODIFY) < 0) return R_NONE;
		}
		return R_TRUE;
		break;

	case A_INDEXQ:
		SET_INTEGER(D_OUT, file->special.file.index + 1);
		break;

	case A_LENGTHQ:
		SET_INTEGER(D_OUT, file->special.file.size - file->special.file.index); // !clip at zero
		break;

	case A_HEAD:
		file->special.file.index = 0;
		goto seeked;

    case A_TAIL:
		file->special.file.index = file->special.file.size;
		goto seeked;

	case A_NEXT:
		file->special.file.index++;
		goto seeked;

	case A_BACK:
		if (file->special.file.index > 0) file->special.file.index--;
		goto seeked;

	case A_SKIP:
		file->special.file.index += Get_Num_Arg(D_ARG(2));
		goto seeked;

    case A_HEADQ:
		DECIDE(file->special.file.index == 0);

    case A_TAILQ:
		DECIDE(file->special.file.index >= file->special.file.size);

    case A_PASTQ:
		DECIDE(file->special.file.index > file->special.file.size);

	case A_CLEAR:
		// !! check for write enabled?
		SET_FLAG(file->modes, RFM_RESEEK);
		SET_FLAG(file->modes, RFM_TRUNCATE);
		file->length = 0;
		if (OS_DO_DEVICE(file, RDC_WRITE) < 0) Trap1_DEAD_END(RE_WRITE_ERROR, path);
		break;

	/* Not yet implemented:
		A_AT,					// 38
		A_PICK,					// 41
		A_PATH,					// 42
		A_PATH_SET,				// 43
		A_FIND,					// 44
		A_SELECT,				// 45
		A_TAKE,					// 49
		A_INSERT,				// 50
		A_REMOVE,				// 52
		A_CHANGE,				// 53
		A_POKE,					// 54
		A_QUERY,				// 64
		A_FLUSH,				// 65
	*/

	default:
		Trap_Action_DEAD_END(REB_PORT, action);
	}

	return R_OUT;

seeked:
	SET_FLAG(file->modes, RFM_RESEEK);
	return R_ARG1;

is_true:
	return R_TRUE;

is_false:
	return R_FALSE;
}
Exemplo n.º 12
0
Arquivo: p-dir.c Projeto: 51weekend/r3
*/	static int Dir_Actor(REBVAL *ds, REBSER *port, REBCNT action)
/*
**		Internal port handler for file directories.
**
***********************************************************************/
{
	REBVAL *spec;
	REBVAL *path;
	REBVAL *state;
	REBREQ dir;
	REBCNT args = 0;
	REBINT result;
	REBCNT len;
	//REBYTE *flags;

	Validate_Port(port, action);

	*D_RET = *D_ARG(1);
	CLEARS(&dir);

	// Validate and fetch relevant PORT fields:
	spec  = BLK_SKIP(port, STD_PORT_SPEC);
	if (!IS_OBJECT(spec)) Trap1(RE_INVALID_SPEC, spec);
	path = Obj_Value(spec, STD_PORT_SPEC_HEAD_REF);
	if (!path) Trap1(RE_INVALID_SPEC, spec);

	if (IS_URL(path)) path = Obj_Value(spec, STD_PORT_SPEC_HEAD_PATH);
	else if (!IS_FILE(path)) Trap1(RE_INVALID_SPEC, path);
	
	state = BLK_SKIP(port, STD_PORT_STATE); // if block, then port is open.

	//flags = Security_Policy(SYM_FILE, path);

	// Get or setup internal state data:
	dir.port = port;
	dir.device = RDI_FILE;

	switch (action) {

	case A_READ:
		//Trap_Security(flags[POL_READ], POL_READ, path);
		args = Find_Refines(ds, ALL_READ_REFS);
		if (!IS_BLOCK(state)) {		// !!! ignores /SKIP and /PART, for now
			Init_Dir_Path(&dir, path, 1, POL_READ);
			Set_Block(state, Make_Block(7)); // initial guess
			result = Read_Dir(&dir, VAL_SERIES(state));
			///OS_FREE(dir.file.path);
			if (result < 0) Trap_Port(RE_CANNOT_OPEN, port, dir.error);
			*D_RET = *state;
			SET_NONE(state);
		} else {
			len = VAL_BLK_LEN(state);
			// !!? Why does this need to copy the block??
			Set_Block(D_RET, Copy_Block_Values(VAL_SERIES(state), 0, len, TS_STRING));
		}
		break;

	case A_CREATE:
		//Trap_Security(flags[POL_WRITE], POL_WRITE, path);
		if (IS_BLOCK(state)) Trap1(RE_ALREADY_OPEN, path); // already open
create:
		Init_Dir_Path(&dir, path, 0, POL_WRITE | REMOVE_TAIL_SLASH); // Sets RFM_DIR too
		result = OS_DO_DEVICE(&dir, RDC_CREATE);
		///OS_FREE(dir.file.path);
		if (result < 0) Trap1(RE_NO_CREATE, path);
		if (action == A_CREATE) return R_ARG2;
		SET_NONE(state);
		break;

	case A_RENAME:
		if (IS_BLOCK(state)) Trap1(RE_ALREADY_OPEN, path); // already open
		else {
			REBSER *target;

			Init_Dir_Path(&dir, path, 0, POL_WRITE | REMOVE_TAIL_SLASH); // Sets RFM_DIR too
			// Convert file name to OS format:
			if (!(target = Value_To_OS_Path(D_ARG(2)))) Trap1(RE_BAD_FILE_PATH, D_ARG(2));
			dir.data = BIN_DATA(target);
			OS_DO_DEVICE(&dir, RDC_RENAME);
			Free_Series(target);
			if (dir.error) Trap1(RE_NO_RENAME, path);
		}
		break;

	case A_DELETE:
		//Trap_Security(flags[POL_WRITE], POL_WRITE, path);
		SET_NONE(state);
		Init_Dir_Path(&dir, path, 0, POL_WRITE);
		// !!! add *.r deletion
		// !!! add recursive delete (?)
		result = OS_DO_DEVICE(&dir, RDC_DELETE);
		///OS_FREE(dir.file.path);
		if (result < 0) Trap1(RE_NO_DELETE, path);
		return R_ARG2;

	case A_OPEN:
		// !! If open fails, what if user does a READ w/o checking for error?
		if (IS_BLOCK(state)) Trap1(RE_ALREADY_OPEN, path); // already open
		//Trap_Security(flags[POL_READ], POL_READ, path);
		args = Find_Refines(ds, ALL_OPEN_REFS);
		if (args & AM_OPEN_NEW) goto create;
		//if (args & ~AM_OPEN_READ) Trap1(RE_INVALID_SPEC, path);
		Set_Block(state, Make_Block(7));
		Init_Dir_Path(&dir, path, 1, POL_READ);
		result = Read_Dir(&dir, VAL_SERIES(state));
		///OS_FREE(dir.file.path);
		if (result < 0) Trap_Port(RE_CANNOT_OPEN, port, dir.error);
		break;

	case A_OPENQ:
		if (IS_BLOCK(state)) return R_TRUE;
		return R_FALSE;

	case A_CLOSE:
		SET_NONE(state);
		break;

	case A_QUERY:
		//Trap_Security(flags[POL_READ], POL_READ, path);
		SET_NONE(state);
		Init_Dir_Path(&dir, path, -1, REMOVE_TAIL_SLASH | POL_READ);
		if (OS_DO_DEVICE(&dir, RDC_QUERY) < 0) return R_NONE;
		Ret_Query_File(port, &dir, D_RET);
		///OS_FREE(dir.file.path);
		break;

	//-- Port Series Actions (only called if opened as a port)

	case A_LENGTHQ:
		len = IS_BLOCK(state) ? VAL_BLK_LEN(state) : 0;
		SET_INTEGER(D_RET, len);
		break;

	default:
		Trap_Action(REB_PORT, action);
	}

	return R_RET;
}
Exemplo n.º 13
0
static int romfs_readdir(FAR struct inode *mountpt,
                         FAR struct fs_dirent_s *dir)
{
  FAR struct romfs_mountpt_s *rm;
  uint32_t                    linkoffset;
  uint32_t                    next;
  uint32_t                    info;
  uint32_t                    size;
  int                         ret;

  fvdbg("Entry\n");

  /* Sanity checks */

  DEBUGASSERT(mountpt != NULL && mountpt->i_private != NULL);

  /* Recover our private data from the inode instance */

  rm = mountpt->i_private;

  /* Make sure that the mount is still healthy */

  romfs_semtake(rm);
  ret = romfs_checkmount(rm);
  if (ret != OK)
    {
      fdbg("romfs_checkmount failed: %d\n", ret);
      goto errout_with_semaphore;
    }

  /* Loop, skipping over unsupported items in the file system */

  for (;;)
    {
      /* Have we reached the end of the directory */

      if (!dir->u.romfs.fr_curroffset)
        {
          /* We signal the end of the directory by returning the
           * special error -ENOENT
           */

          fdbg("End of directory\n");
          ret = -ENOENT;
          goto errout_with_semaphore;
        }

      /* Parse the directory entry */

      ret = romfs_parsedirentry(rm, dir->u.romfs.fr_curroffset, &linkoffset,
                                &next, &info, &size);
      if (ret < 0)
        {
          fdbg("romfs_parsedirentry failed: %d\n", ret);
          goto errout_with_semaphore;
        }

      /* Save the filename */

      ret = romfs_parsefilename(rm, dir->u.romfs.fr_curroffset, dir->fd_dir.d_name);
      if (ret < 0)
        {
          fdbg("romfs_parsefilename failed: %d\n", ret);
          goto errout_with_semaphore;
        }

      /* Set up the next directory entry offset */

      dir->u.romfs.fr_curroffset = next & RFNEXT_OFFSETMASK;

      /* Check the file type */

      if (IS_DIRECTORY(next))
        {
          dir->fd_dir.d_type = DTYPE_DIRECTORY;
          break;
        }
      else if (IS_FILE(next))
        {
          dir->fd_dir.d_type = DTYPE_FILE;
          break;
        }
    }

errout_with_semaphore:
  romfs_semgive(rm);
  return ret;
}
Exemplo n.º 14
0
static int romfs_stat(FAR struct inode *mountpt, FAR const char *relpath,
                      FAR struct stat *buf)
{
  FAR struct romfs_mountpt_s *rm;
  FAR struct romfs_dirinfo_s dirinfo;
  int ret;

  fvdbg("Entry\n");

  /* Sanity checks */

  DEBUGASSERT(mountpt && mountpt->i_private);

  /* Get the mountpoint private data from the inode structure */

  rm = mountpt->i_private;

  /* Check if the mount is still healthy */

  romfs_semtake(rm);
  ret = romfs_checkmount(rm);
  if (ret != OK)
    {
      fdbg("romfs_checkmount failed: %d\n", ret);
      goto errout_with_semaphore;
    }

  /* Find the directory entry corresponding to relpath. */

  ret = romfs_finddirentry(rm, &dirinfo, relpath);

  /* If nothing was found, then we fail with EEXIST */

  if (ret < 0)
    {
      fvdbg("Failed to find directory: %d\n", ret);
      goto errout_with_semaphore;
    }

  memset(buf, 0, sizeof(struct stat));
  if (IS_DIRECTORY(dirinfo.rd_next))
    {
      /* It's a read-only directory name */

      buf->st_mode = S_IFDIR|S_IROTH|S_IRGRP|S_IRUSR;
      if (IS_EXECUTABLE(dirinfo.rd_next))
        {
          buf->st_mode |= S_IXOTH|S_IXGRP|S_IXUSR;
        }
    }
  else if (IS_FILE(dirinfo.rd_next))
    {
      /* It's a read-only file name */

      buf->st_mode = S_IFREG|S_IROTH|S_IRGRP|S_IRUSR;
      if (IS_EXECUTABLE(dirinfo.rd_next))
        {
          buf->st_mode |= S_IXOTH|S_IXGRP|S_IXUSR;
        }
    }
  else
    {
      /* Otherwise, pretend like the unsupported node does not exist */

      fvdbg("Unsupported inode: %d\n", dirinfo.rd_next);
      ret = -ENOENT;
      goto errout_with_semaphore;
    }

  /* File/directory size, access block size */

  buf->st_size      = dirinfo.rd_size;
  buf->st_blksize   = rm->rm_hwsectorsize;
  buf->st_blocks    = (buf->st_size + buf->st_blksize - 1) / buf->st_blksize;

  ret = OK;

errout_with_semaphore:
  romfs_semgive(rm);
  return ret;
}
Exemplo n.º 15
0
static int
fatfs_rename(vnode_t dvp1, vnode_t vp1, char *name1,
             vnode_t dvp2, vnode_t vp2, char *name2)
{
    struct fatfsmount *fmp;
    struct fatfs_node np1;
    struct fat_dirent *de1, *de2;
    int error;

    fmp = dvp1->v_mount->m_data;
    mutex_lock(&fmp->lock);

    error = fatfs_lookup_node(dvp1, name1, &np1);
    if (error)
        goto out;
    de1 = &np1.dirent;

    if (IS_FILE(de1)) {
        /* Remove destination file, first */
        error = fatfs_remove(dvp2, vp1, name2);
        if (error == EIO)
            goto out;

        /* Change file name of directory entry */
        fat_convert_name(name2, (char *)de1->name);

        /* Same directory ? */
        if (dvp1 == dvp2) {
            /* Change the name of existing file */
            error = fatfs_put_node(fmp, &np1);
            if (error)
                goto out;
        } else {
            /* Create new directory entry */
            error = fatfs_add_node(dvp2, &np1);
            if (error)
                goto out;

            /* Remove souce file */
            error = fatfs_remove(dvp1, vp2, name1);
            if (error)
                goto out;
        }
    } else {

        /* remove destination directory */
        error = fatfs_rmdir(dvp2, NULL, name2);
        if (error == EIO)
            goto out;

        /* Change file name of directory entry */
        fat_convert_name(name2, (char *)de1->name);

        /* Same directory ? */
        if (dvp1 == dvp2) {
            /* Change the name of existing directory */
            error = fatfs_put_node(fmp, &np1);
            if (error)
                goto out;
        } else {
            /* Create new directory entry */
            error = fatfs_add_node(dvp2, &np1);
            if (error)
                goto out;

            /* Update "." and ".." for renamed directory */
            if (fat_read_cluster(fmp,(de1->cluster_hi << 16) |  de1->cluster)) {
                error = EIO;
                goto out;
            }

            de2 = (struct fat_dirent *)fmp->io_buf;
            de2->cluster_hi = de1->cluster_hi;
            de2->cluster = de1->cluster;
            de2->time = TEMP_TIME;
            de2->date = TEMP_DATE;
            de2++;
            de2->cluster_hi = (dvp2->v_blkno & 0xFFFF0000) >> 16;
            de2->cluster = dvp2->v_blkno & 0x0000FFFF;
            de2->time = TEMP_TIME;
            de2->date = TEMP_DATE;

            if (fat_write_cluster(fmp,(de1->cluster_hi << 16) |  de1->cluster)) {
                error = EIO;
                goto out;
            }

            /* Remove souce directory */
            error = fatfs_rmdir(dvp1, NULL, name1);
            if (error)
                goto out;
        }
    }
out:
    mutex_unlock(&fmp->lock);
    return error;
}
Exemplo n.º 16
0
//
//  Serial_Actor: C
//
static REB_R Serial_Actor(REBFRM *frame_, REBCTX *port, REBSYM action)
{
    REBREQ *req;    // IO request
    REBVAL *spec;   // port spec
    REBVAL *arg;    // action argument value
    REBVAL *val;    // e.g. port number value
    REBINT result;  // IO result
    REBCNT refs;    // refinement argument flags
    REBCNT len;     // generic length
    REBSER *ser;    // simplifier
    REBVAL *path;

    Validate_Port(port, action);

    *D_OUT = *D_ARG(1);

    // Validate PORT fields:
    spec = CTX_VAR(port, STD_PORT_SPEC);
    if (!IS_OBJECT(spec)) fail (Error(RE_INVALID_PORT));
    path = Obj_Value(spec, STD_PORT_SPEC_HEAD_REF);
    if (!path) fail (Error(RE_INVALID_SPEC, spec));

    //if (!IS_FILE(path)) fail (Error(RE_INVALID_SPEC, path));

    req = cast(REBREQ*, Use_Port_State(port, RDI_SERIAL, sizeof(*req)));

    // Actions for an unopened serial port:
    if (!IS_OPEN(req)) {

        switch (action) {

        case SYM_OPEN:
            arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_PATH);
            if (! (IS_FILE(arg) || IS_STRING(arg) || IS_BINARY(arg)))
                fail (Error(RE_INVALID_PORT_ARG, arg));

            req->special.serial.path = ALLOC_N(REBCHR, MAX_SERIAL_DEV_PATH);
            OS_STRNCPY(
                req->special.serial.path,
                //
                // !!! This is assuming VAL_DATA contains native chars.
                // Should it? (2 bytes on windows, 1 byte on linux/mac)
                //
                SER_AT(REBCHR, VAL_SERIES(arg), VAL_INDEX(arg)),
                MAX_SERIAL_DEV_PATH
            );
            arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_SPEED);
            if (! IS_INTEGER(arg))
                fail (Error(RE_INVALID_PORT_ARG, arg));

            req->special.serial.baud = VAL_INT32(arg);
            //Secure_Port(SYM_SERIAL, ???, path, ser);
            arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_DATA_SIZE);
            if (!IS_INTEGER(arg)
                || VAL_INT64(arg) < 5
                || VAL_INT64(arg) > 8
            ) {
                fail (Error(RE_INVALID_PORT_ARG, arg));
            }
            req->special.serial.data_bits = VAL_INT32(arg);

            arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_STOP_BITS);
            if (!IS_INTEGER(arg)
                || VAL_INT64(arg) < 1
                || VAL_INT64(arg) > 2
            ) {
                fail (Error(RE_INVALID_PORT_ARG, arg));
            }
            req->special.serial.stop_bits = VAL_INT32(arg);

            arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_PARITY);
            if (IS_BLANK(arg)) {
                req->special.serial.parity = SERIAL_PARITY_NONE;
            } else {
                if (!IS_WORD(arg))
                    fail (Error(RE_INVALID_PORT_ARG, arg));

                switch (VAL_WORD_SYM(arg)) {
                    case SYM_ODD:
                        req->special.serial.parity = SERIAL_PARITY_ODD;
                        break;
                    case SYM_EVEN:
                        req->special.serial.parity = SERIAL_PARITY_EVEN;
                        break;
                    default:
                        fail (Error(RE_INVALID_PORT_ARG, arg));
                }
            }

            arg = Obj_Value(spec, STD_PORT_SPEC_SERIAL_FLOW_CONTROL);
            if (IS_BLANK(arg)) {
                req->special.serial.flow_control = SERIAL_FLOW_CONTROL_NONE;
            } else {
                if (!IS_WORD(arg))
                    fail (Error(RE_INVALID_PORT_ARG, arg));

                switch (VAL_WORD_SYM(arg)) {
                    case SYM_HARDWARE:
                        req->special.serial.flow_control = SERIAL_FLOW_CONTROL_HARDWARE;
                        break;
                    case SYM_SOFTWARE:
                        req->special.serial.flow_control = SERIAL_FLOW_CONTROL_SOFTWARE;
                        break;
                    default:
                        fail (Error(RE_INVALID_PORT_ARG, arg));
                }
            }

            if (OS_DO_DEVICE(req, RDC_OPEN))
                fail (Error_On_Port(RE_CANNOT_OPEN, port, -12));
            SET_OPEN(req);
            return R_OUT;

        case SYM_CLOSE:
            return R_OUT;

        case SYM_OPEN_Q:
            return R_FALSE;

        default:
            fail (Error_On_Port(RE_NOT_OPEN, port, -12));
        }
    }

    // Actions for an open socket:
    switch (action) {

    case SYM_READ:
        refs = Find_Refines(frame_, ALL_READ_REFS);

        // Setup the read buffer (allocate a buffer if needed):
        arg = CTX_VAR(port, STD_PORT_DATA);
        if (!IS_STRING(arg) && !IS_BINARY(arg)) {
            Val_Init_Binary(arg, Make_Binary(32000));
        }
        ser = VAL_SERIES(arg);
        req->length = SER_AVAIL(ser); // space available
        if (req->length < 32000/2) Extend_Series(ser, 32000);
        req->length = SER_AVAIL(ser);

        // This used STR_TAIL (obsolete, equivalent to BIN_TAIL) but was it
        // sure the series was byte sized?  Added in a check.
        assert(BYTE_SIZE(ser));
        req->common.data = BIN_TAIL(ser); // write at tail

        //if (SER_LEN(ser) == 0)
        req->actual = 0;  // Actual for THIS read, not for total.
#ifdef DEBUG_SERIAL
        printf("(max read length %d)", req->length);
#endif
        result = OS_DO_DEVICE(req, RDC_READ); // recv can happen immediately
        if (result < 0) fail (Error_On_Port(RE_READ_ERROR, port, req->error));
#ifdef DEBUG_SERIAL
        for (len = 0; len < req->actual; len++) {
            if (len % 16 == 0) printf("\n");
            printf("%02x ", req->common.data[len]);
        }
        printf("\n");
#endif
        *D_OUT = *arg;
        return R_OUT;

    case SYM_WRITE:
        refs = Find_Refines(frame_, ALL_WRITE_REFS);

        // Determine length. Clip /PART to size of string if needed.
        spec = D_ARG(2);
        len = VAL_LEN_AT(spec);
        if (refs & AM_WRITE_PART) {
            REBCNT n = Int32s(D_ARG(ARG_WRITE_LIMIT), 0);
            if (n <= len) len = n;
        }

        // Setup the write:
        *CTX_VAR(port, STD_PORT_DATA) = *spec;  // keep it GC safe
        req->length = len;
        req->common.data = VAL_BIN_AT(spec);
        req->actual = 0;

        //Print("(write length %d)", len);
        result = OS_DO_DEVICE(req, RDC_WRITE); // send can happen immediately
        if (result < 0) fail (Error_On_Port(RE_WRITE_ERROR, port, req->error));
        break;

    case SYM_UPDATE:
        // Update the port object after a READ or WRITE operation.
        // This is normally called by the WAKE-UP function.
        arg = CTX_VAR(port, STD_PORT_DATA);
        if (req->command == RDC_READ) {
            if (ANY_BINSTR(arg)) {
                SET_SERIES_LEN(
                    VAL_SERIES(arg),
                    VAL_LEN_HEAD(arg) + req->actual
                );
            }
        }
        else if (req->command == RDC_WRITE) {
            SET_BLANK(arg);  // Write is done.
        }
        return R_BLANK;

    case SYM_OPEN_Q:
        return R_TRUE;

    case SYM_CLOSE:
        if (IS_OPEN(req)) {
            OS_DO_DEVICE(req, RDC_CLOSE);
            SET_CLOSED(req);
        }
        break;

    default:
        fail (Error_Illegal_Action(REB_PORT, action));
    }

    return R_OUT;
}
Exemplo n.º 17
0
int make_assumptions(child_args_t *args)
{
	char TmpStr[80];
	struct stat stat_buf;
	int rv;

	if (!(args->flags & CLD_FLG_IOTYPS)) {
		/* use stat to get file properties, and use to set -I */
		rv = stat(args->device, &stat_buf);
		if (0 == rv) {
			if (IS_FILE(stat_buf.st_mode)) {
				strncat(args->argstr, "(-I f) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
				args->flags |= CLD_FLG_FILE;
			} else if (IS_BLK(stat_buf.st_mode)) {
				strncat(args->argstr, "(-I b) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
				args->flags |= CLD_FLG_BLK;
#ifndef WINDOWS
			} else if (S_ISCHR(stat_buf.st_mode)) {
				strncat(args->argstr, "(-I r) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
				args->flags |= CLD_FLG_RAW;
#endif
			}
		} else {
			pMsg(WARN, args, "Can't get status on %s, defaulting to file, errno = %d\n", args->device, GETLASTERROR());
			strncat(args->argstr, "(-I f) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
			args->flags |= CLD_FLG_FILE;
		}
	}
	if ((args->flags & CLD_FLG_WFSYNC) && (0 == args->sync_interval)) {
		pMsg(INFO, args, "Sync interval set to zero, assuming interval of 1.\n");
		args->sync_interval = 1;
	}

	if (args->ltrsiz <= 0) {
		sprintf(TmpStr, "(-B %d) ", TRSIZ*BLK_SIZE);
		strncat(args->argstr, TmpStr, (MAX_ARG_LEN-1)-strlen(args->argstr));
		args->ltrsiz=TRSIZ;
		args->htrsiz=TRSIZ;
	}
	if (args->flags & CLD_FLG_LBA_RNG) {
		args->start_blk = args->start_lba / args->htrsiz;
		if (!(args->stop_lba < 0))
			args->stop_blk = args->stop_lba / args->htrsiz;
	}
	if (args->flags & CLD_FLG_BLK_RNG) {
		args->start_lba = args->start_blk * args->htrsiz;
		if (!(args->stop_blk < 0))
			args->stop_lba = (args->stop_blk * args->htrsiz) + (args->htrsiz - 1);
	}
	/* if vsiz is still not set, try and get it from the file */
	if ((args->vsiz <=0) && (args->flags & CLD_FLG_FILE)) {
		if (0 != get_file_size(args->device)) { /* file size retrieved */
			args->vsiz=get_file_size(args->device);
		}
	}
	/* if vsiz is still not set, try and get it from the device */
	if ((args->vsiz <= 0) && !(args->flags & CLD_FLG_FILE)) {
		args->vsiz=get_vsiz(args->device);
	}
	/* if vsiz is still not set, set based on given range */
	if ((args->vsiz <=0) && (args->flags & (CLD_FLG_LBA_RNG|CLD_FLG_BLK_RNG))) {
		if (!(args->stop_lba < 0))
			args->vsiz=args->stop_lba+1;
		else
			args->vsiz=args->start_lba+1;
	}
	/* if vsiz is still not set, then set it to the default size */
	if (args->vsiz <= 0) {
		args->vsiz=VSIZ;
	}
	if (!(args->flags & CLD_FLG_VSIZ)) {
		sprintf(TmpStr, N_ASSUME, args->vsiz);
		strncat(args->argstr, TmpStr, (MAX_ARG_LEN-1)-strlen(args->argstr));
	}

	if (args->stop_lba == -1) {
		args->stop_lba=args->vsiz-1;
	}
	if (args->stop_blk == -1) {
		args->stop_blk=(args->stop_lba / (OFF_T) args->htrsiz);
	}
	if (args->t_kids == 0) {
		sprintf(TmpStr, "(-K %d) ", KIDS);
		strncat(args->argstr, TmpStr, (MAX_ARG_LEN-1)-strlen(args->argstr));
		args->t_kids=KIDS;
	}
	if ((args->flags & (CLD_FLG_W|CLD_FLG_R)) == 0) {
		if (args->flags & CLD_FLG_DUTY) { /* no read/write but duty cycle specified */
			if (args->rperc > 0) {
				args->flags |= CLD_FLG_R;
				strncat(args->argstr, "(-r) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
			}
			if (args->wperc > 0) {
				args->flags |= CLD_FLG_W;
				strncat(args->argstr, "(-w) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
			}
		} else {
			strncat(args->argstr, "(-r) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
			args->flags |= CLD_FLG_R;
		}
	}
	if (!(args->flags & CLD_FLG_PTYPS)) {
		strncat(args->argstr, "(-c) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
		args->flags |= CLD_FLG_CPTYPE;
	}
	if (!(args->flags & CLD_FLG_SKTYPS)) {
		strncat(args->argstr, "(-p R) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
		args->flags |= CLD_FLG_RANDOM;
	}
	if (!(args->flags & CLD_FLG_SKS)) {
		if (args->start_blk == args->stop_blk) { /* diskcache test, w/ no seek count set */
			args->seeks = SEEKS;
		} else if (args->flags & (CLD_FLG_BLK_RNG|CLD_FLG_LBA_RNG)) { /* range set, w/ no seek count */
			args->seeks = args->stop_blk - args->start_blk + 1;
		} else {
			/* if vsiz is available, calculated seeks are in terms of the largest transfer size */
			args->seeks = (args->vsiz > 0) ? (args->vsiz / args->htrsiz) : SEEKS;
		}
		if ((args->flags & CLD_FLG_LINEAR) && (args->flags & CLD_FLG_R) && (args->flags & CLD_FLG_W)) {
			args->seeks *= 2;
		}

		if (!(args->flags & CLD_FLG_TMD)) {
			sprintf(TmpStr, L_ASSUME, args->seeks);
			strncat(args->argstr, TmpStr, (MAX_ARG_LEN-1)-strlen(args->argstr));
		}
	}
	if (!(args->flags & (CLD_FLG_SKS|CLD_FLG_TMD)) || ((args->flags & CLD_FLG_CYC) && !(args->flags & (CLD_FLG_SKS|CLD_FLG_TMD)))) {
		args->flags |= CLD_FLG_SKS;
	}
	if (args->flags & (CLD_FLG_LINEAR)) {
		if (!(args->flags & (CLD_FLG_LUNU|CLD_FLG_LUND))) {
			strncat(args->argstr, "(-p u) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
			args->flags |= CLD_FLG_LUNU;
		}
	}
	normalize_percs(args);
	if (!(args->flags & CLD_FLG_DUTY) && (args->flags & CLD_FLG_RANDOM) && !(args->flags & CLD_FLG_NTRLVD)) {
		sprintf(TmpStr, "(-D %d:%d) ", args->rperc, args->wperc);
		strncat(args->argstr, TmpStr, (MAX_ARG_LEN-1)-strlen(args->argstr));
		args->flags |= CLD_FLG_DUTY;
	}
	if ((args->delayTimeMin == 0) && (args->delayTimeMax == 0) && (args->ioTimeout == DEFAULT_IO_TIMEOUT)) {
		strncat(args->argstr, "(-t 0:2m) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
	}
	if (!(args->flags & CLD_FLG_OFFSET)) {
		strncat(args->argstr, "(-o 0) ", (MAX_ARG_LEN-1)-strlen(args->argstr));
	}

	return 0;
}
Exemplo n.º 18
0
/*
 * checks validity of data after parsing
 * args and make assumtions. returns 0 on
 * success and -1 on failure.
 */
int check_conclusions(child_args_t *args)
{
	extern unsigned long glb_flags;
	struct stat stat_buf;
	int rv;

	if ((args->flags & CLD_FLG_DUTY) && ((args->flags & CLD_FLG_LINEAR) || (args->flags & CLD_FLG_NTRLVD))) {
		pMsg(WARN, args, "Duty cycle testing is supported for random (-pR) tests only.\n");
		return(-1);
	}
	if ((args->flags & CLD_FLG_BLK_RNG) && (args->flags & CLD_FLG_RTRSIZ)) {
		pMsg(WARN, args, "Can't have unfixed block sizes and specify seek range in terms of blocks.\n");
		return(-1);
	}
	if ((args->vsiz < 0) || (args->ltrsiz < 1) || (args->htrsiz < 1)) {
		pMsg(WARN, args, "Bounds exceeded for transfer size and/or volume size.\n");
		pMsg(WARN, args, MAXTRSIZ, (args->htrsiz*BLK_SIZE),args->vsiz);
		return(-1);
	}
	if (args->htrsiz < args->ltrsiz) {
		pMsg(ERR, args, "Min transfer size, %lu, greater then Max transfer size, %lu.\n", args->ltrsiz, args->htrsiz);
		return(-1);
	}
	if (args->vsiz < (args->stop_lba-args->start_lba+1)) {
		pMsg(ERR, args, "Volume stop block/lba exceeds volume size.\n");
		return(-1);
	}
	if (args->vsiz < args->htrsiz) {
		pMsg(WARN, args, VSIZETS, args->vsiz, args->htrsiz);
		return(-1);
	}
	if ((args->flags & CLD_FLG_TMD) == 0 && (args->seeks <= 0)) {
		pMsg(WARN,args, TSEEK, args->seeks);
		return(-1);
	}
	if ((args->flags & CLD_FLG_SKS) && (args->t_kids > args->seeks)) {
		pMsg(WARN, args, "Can't have more children then max number of seeks, use -K/-L to adjust.\n");
		return(-1);
	}
	if ((args->start_blk > args->vsiz) && !(args->flags & (CLD_FLG_BLK_RNG|CLD_FLG_LBA_RNG))) {
		pMsg(WARN, args, STBGTTLBA, args->start_blk, (args->vsiz / args->htrsiz));
		return(-1);
	}
	if ((args->stop_blk > args->vsiz) && !(args->flags & (CLD_FLG_BLK_RNG|CLD_FLG_LBA_RNG))) {
		pMsg(WARN, args, SBGTTLBA, args->stop_blk, (args->vsiz / args->htrsiz));
		return(-1);
	}
	if ((args->start_lba > args->vsiz) && !(args->flags & (CLD_FLG_BLK_RNG|CLD_FLG_LBA_RNG))) {
		pMsg(WARN, args, STLBAGTLBA, args->start_lba, args->vsiz);
		return(-1);
	}
	if ((args->stop_lba > args->vsiz) && !(args->flags & (CLD_FLG_BLK_RNG|CLD_FLG_LBA_RNG))) {
		pMsg(WARN, args, SLBAGTLBA, args->stop_lba, args->vsiz);
		return(-1);
	}
	if (args->start_blk > args->stop_blk) {
		pMsg(WARN, args, SBRSB, args->stop_blk, args->start_blk);
		return(-1);
	}
	if (args->start_lba > args->stop_lba) {
		pMsg(ERR, args, SLBARSLBA, args->stop_lba, args->start_lba);
		return(-1);
	}
	if ((args->flags & CLD_FLG_LBA_RNG) && (args->flags & CLD_FLG_BLK_RNG)) {
		pMsg(ERR, args, "Can't specify range in both block and LBA, use -s or -S.\n");
		return(-1);
	}

	/* use stat to get file properties, and test then agains specified -I */
	rv = stat(args->device, &stat_buf);
	if (0 == rv) { /* no error on call to stat, compare against -I option */
		/* files are usually file type */
		if ((args->flags & CLD_FLG_FILE) && !IS_FILE(stat_buf.st_mode)) {
			pMsg(ERR, args, "Can't open non-file filespec with file device type, -If.\n");
			return(-1);
		}
		/* block devices, are usually block type */
		if ((args->flags & CLD_FLG_BLK) && !IS_BLK(stat_buf.st_mode)) {
			pMsg(ERR, args, "Can't open non-block filespec with block device type, -Ib.\n");
			return(-1);
		}
#ifndef WINDOWS
		/* raw devices, are usually character type */
		if ((args->flags & CLD_FLG_RAW) && !S_ISCHR(stat_buf.st_mode)) {
			pMsg(ERR, args, "Can't open non-raw filespec with raw device type, -Ir.\n");
			return(-1);
		}
#else
		if (args->flags & CLD_FLG_RAW) {
			pMsg(ERR, args, "RAW IO type not supported in Windows, use direct IO instead.\n");
			return(-1);
		}
#endif
#ifdef _DEBUG
	} else {
		PDBG1(DBUG, args, "Can't get status on %s, assuming a new file, errno = %d\n", args->device, GETLASTERROR());
#endif
	}

	if ((args->hbeat > 0) && (args->flags & CLD_FLG_TMD) && (args->hbeat > args->run_time)) {
		pMsg(ERR, args, "Heartbeat should be at least equal to runtime, use -h/-T to adjust.\n");
		return(-1);
	}
	if ((args->hbeat > 0) && !(args->flags & CLD_FLG_PRFTYPS)) {
		pMsg(ERR, args, "At least one performance option, -P, must be specified when using -h.\n");
		return(-1);
	}
	if ((args->flags & CLD_FLG_W) && !(args->flags & CLD_FLG_R) && (args->flags & CLD_FLG_CMPR)) {
		pMsg(ERR, args, "Write only, ignoring option -E.\n");
	}
	if ((args->flags & CLD_FLG_TMD) && (args->flags & CLD_FLG_SKS)) {
		pMsg(ERR, args, "Can't specify both -L and -T they are mutually exclusive.\n");
		return(-1);
	}
	if (((args->flags & CLD_FLG_R) && !(args->flags & CLD_FLG_W)) && (args->flags & CLD_FLG_ERR_MARK)) {
		pMsg(ERR, args, "Can't specify mark on error, -Am, in read only mode.\n");
		return(-1);
	}
	if (!(args->flags & CLD_FLG_ALLDIE) && (args->flags & CLD_FLG_ERR_MARK)) {
		pMsg(ERR, args, "Can't specify mark on error, -Am, when continue on error is set.\n");
		return(-1);
	}
	if ((glb_flags & GLB_FLG_KILL) && !(args->flags & CLD_FLG_ALLDIE)) {
		pMsg(ERR, args, "Can't specify global kill, -Ag, when continue on error is set, -Ac.\n");
		return(-1);
	}
	if ((args->flags & CLD_FLG_LINEAR) && !(args->flags & CLD_FLG_NTRLVD) && (args->flags & CLD_FLG_TMD)) {
		pMsg(ERR, args, "Linear read / write test can not be timed.\n");
		return(-1);
	}
	if ((args->flags & CLD_FLG_CMPR) && (args->cmp_lng > (args->ltrsiz*BLK_SIZE))) {
		pMsg(ERR, args, "Compare length, %lu, is greater then transfer size, %lu\n", args->cmp_lng, args->ltrsiz*BLK_SIZE);
		return(-1);
	}
	if ((args->flags & CLD_FLG_OFFSET) && (args->offset > args->stop_lba)) {
		pMsg(ERR, args, LBAOFFGSLBA, args->offset, args->stop_lba);
		return(-1);
	}
	if ((args->flags & CLD_FLG_OFFSET) && ((args->offset+args->ltrsiz-1) > args->stop_lba)) {
		pMsg(ERR, args, LBAOTSGSLBA, args->offset, args->ltrsiz, args->stop_lba);
		return(-1);
	}
	return 0;
}
Exemplo n.º 19
0
*/	static REB_R Dir_Actor(struct Reb_Call *call_, REBSER *port, REBCNT action)
/*
**		Internal port handler for file directories.
**
***********************************************************************/
{
	REBVAL *spec;
	REBVAL *path;
	REBVAL *state;
	REBREQ dir;
	REBCNT args = 0;
	REBINT result;
	REBCNT len;
	//REBYTE *flags;

	Validate_Port(port, action);

	*D_OUT = *D_ARG(1);
	CLEARS(&dir);

	// Validate and fetch relevant PORT fields:
	spec  = BLK_SKIP(port, STD_PORT_SPEC);
	if (!IS_OBJECT(spec)) raise Error_1(RE_INVALID_SPEC, spec);
	path = Obj_Value(spec, STD_PORT_SPEC_HEAD_REF);
	if (!path) raise Error_1(RE_INVALID_SPEC, spec);

	if (IS_URL(path)) path = Obj_Value(spec, STD_PORT_SPEC_HEAD_PATH);
	else if (!IS_FILE(path)) raise Error_1(RE_INVALID_SPEC, path);

	state = BLK_SKIP(port, STD_PORT_STATE); // if block, then port is open.

	//flags = Security_Policy(SYM_FILE, path);

	// Get or setup internal state data:
	dir.port = port;
	dir.device = RDI_FILE;

	switch (action) {

	case A_READ:
		//Trap_Security(flags[POL_READ], POL_READ, path);
		args = Find_Refines(call_, ALL_READ_REFS);
		if (!IS_BLOCK(state)) {		// !!! ignores /SKIP and /PART, for now
			Init_Dir_Path(&dir, path, 1, POL_READ);
			Val_Init_Block(state, Make_Array(7)); // initial guess
			result = Read_Dir(&dir, VAL_SERIES(state));
			///OS_FREE(dir.file.path);
			if (result < 0)
				raise Error_On_Port(RE_CANNOT_OPEN, port, dir.error);
			*D_OUT = *state;
			SET_NONE(state);
		}
		else {
			// !!! This copies the strings in the block, shallowly.  What is
			// the purpose of doing this?  Why copy at all?
			Val_Init_Block(
				D_OUT,
				Copy_Array_Core_Managed(
					VAL_SERIES(state),
					0,
					VAL_BLK_LEN(state),
					FALSE, // !deep
					TS_STRING
				)
			);
		}
		break;

	case A_CREATE:
		//Trap_Security(flags[POL_WRITE], POL_WRITE, path);
		if (IS_BLOCK(state)) raise Error_1(RE_ALREADY_OPEN, path);
create:
		Init_Dir_Path(&dir, path, 0, POL_WRITE | REMOVE_TAIL_SLASH); // Sets RFM_DIR too
		result = OS_DO_DEVICE(&dir, RDC_CREATE);
		///OS_FREE(dir.file.path);
		if (result < 0) raise Error_1(RE_NO_CREATE, path);
		if (action == A_CREATE) {
			// !!! Used to return R_ARG2, but create is single arity.  :-/
			return R_ARG1;
		}
		SET_NONE(state);
		break;

	case A_RENAME:
		if (IS_BLOCK(state)) raise Error_1(RE_ALREADY_OPEN, path);
		else {
			REBSER *target;

			Init_Dir_Path(&dir, path, 0, POL_WRITE | REMOVE_TAIL_SLASH); // Sets RFM_DIR too
			// Convert file name to OS format:
			if (!(target = Value_To_OS_Path(D_ARG(2), TRUE)))
				raise Error_1(RE_BAD_FILE_PATH, D_ARG(2));
			dir.common.data = BIN_DATA(target);
			OS_DO_DEVICE(&dir, RDC_RENAME);
			Free_Series(target);
			if (dir.error) raise Error_1(RE_NO_RENAME, path);
		}
		break;

	case A_DELETE:
		//Trap_Security(flags[POL_WRITE], POL_WRITE, path);
		SET_NONE(state);
		Init_Dir_Path(&dir, path, 0, POL_WRITE);
		// !!! add *.r deletion
		// !!! add recursive delete (?)
		result = OS_DO_DEVICE(&dir, RDC_DELETE);
		///OS_FREE(dir.file.path);
		if (result < 0) raise Error_1(RE_NO_DELETE, path);
		// !!! Returned R_ARG2 before, but there is no second argument :-/
		return R_ARG1;

	case A_OPEN:
		// !! If open fails, what if user does a READ w/o checking for error?
		if (IS_BLOCK(state)) raise Error_1(RE_ALREADY_OPEN, path);
		//Trap_Security(flags[POL_READ], POL_READ, path);
		args = Find_Refines(call_, ALL_OPEN_REFS);
		if (args & AM_OPEN_NEW) goto create;
		//if (args & ~AM_OPEN_READ) raise Error_1(RE_INVALID_SPEC, path);
		Val_Init_Block(state, Make_Array(7));
		Init_Dir_Path(&dir, path, 1, POL_READ);
		result = Read_Dir(&dir, VAL_SERIES(state));
		///OS_FREE(dir.file.path);
		if (result < 0) raise Error_On_Port(RE_CANNOT_OPEN, port, dir.error);
		break;

	case A_OPENQ:
		if (IS_BLOCK(state)) return R_TRUE;
		return R_FALSE;

	case A_CLOSE:
		SET_NONE(state);
		break;

	case A_QUERY:
		//Trap_Security(flags[POL_READ], POL_READ, path);
		SET_NONE(state);
		Init_Dir_Path(&dir, path, -1, REMOVE_TAIL_SLASH | POL_READ);
		if (OS_DO_DEVICE(&dir, RDC_QUERY) < 0) return R_NONE;
		Ret_Query_File(port, &dir, D_OUT);
		///OS_FREE(dir.file.path);
		break;

	//-- Port Series Actions (only called if opened as a port)

	case A_LENGTH:
		len = IS_BLOCK(state) ? VAL_BLK_LEN(state) : 0;
		SET_INTEGER(D_OUT, len);
		break;

	default:
		raise Error_Illegal_Action(REB_PORT, action);
	}

	return R_OUT;
}