int main(int argc, char *argv[]){
	
	if(argc != 2){
		printf("usage:\ntouch file\n");
		return 1;
	}

	putenv("LOCALFS=some_fs.filesystem");
	
	char *fs_name = getenv("LOCALFS");
	
	struct fs *file_system;

	file_system = open_fs(fs_name);
	
	char *file = get_file(file_system, argv[1]);

	if(file == NULL){
		//create the file 
		create_file(file_system, argv[1], "", 0, 0x0000);
	} else {
		// update the timestamp on the file
		update_timestamp(file_system, argv[1]);
	}

	close_fs(file_system);

	return 1;
}
Exemple #2
0
static int sys_close(int fd) {
    if (FD_CHECK(fd)) {
        close_fs(FD_ENTRY(fd));
        FD_ENTRY(fd) = NULL;
        return 0;
    }
    return -1;
}
Exemple #3
0
static int sys_access(const char * file, int flags) {
    PTR_VALIDATE(file);
    debug_print(INFO, "access(%s, 0x%x) from pid=%d", file, flags, getpid());
    fs_node_t * node = kopen((char *)file, 0);
    if (!node) return -1;
    close_fs(node);
    return 0;
}
Exemple #4
0
static int sys_chown(char * file, int uid, int gid) {
	int result;
	PTR_VALIDATE(file);
	fs_node_t * fn = kopen(file, 0);
	if (fn) {
		/* TODO: Owners can change groups... */
		if (current_process->user != 0) {
			close_fs(fn);
			return -EACCES;
		}
		result = chown_fs(fn, uid, gid);
		close_fs(fn);
		return result;
	} else {
		return -ENOENT;
	}
}
Exemple #5
0
static int sys_chmod(char * file, int mode) {
	int result;
	PTR_VALIDATE(file);
	fs_node_t * fn = kopen(file, 0);
	if (fn) {
		/* Can group members change bits? I think it's only owners. */
		if (current_process->user != 0 && current_process->user != fn->uid) {
			close_fs(fn);
			return -EACCES;
		}
		result = chmod_fs(fn, mode);
		close_fs(fn);
		return result;
	} else {
		return -ENOENT;
	}
}
Exemple #6
0
static int sys_statf(char * file, uintptr_t st) {
    int result;
    PTR_VALIDATE(file);
    PTR_VALIDATE(st);
    fs_node_t * fn = kopen(file, 0);
    result = stat_node(fn, st);
    if (fn)
        close_fs(fn);
    return result;
}
Exemple #7
0
static int sys_chmod(char * file, int mode) {
    int result;
    PTR_VALIDATE(file);
    fs_node_t * fn = kopen(file, 0);
    if (fn) {
        result = chmod_fs(fn, mode);
        close_fs(fn);
        return result;
    } else {
        return -1;
    }
}
Exemple #8
0
static int sys_chown(char * file, int uid, int gid) {
	int result;
	PTR_VALIDATE(file);
	fs_node_t * fn = kopen(file, 0);
	if (fn) {
		result = chown_fs(fn, uid, gid);
		close_fs(fn);
		return result;
	} else {
		return -1;
	}
}
Exemple #9
0
int sys_close(int fd)
{
	if (fd < 0 || fd >= NR_OPEN) return -EBADF;
	if (!current_task->files[fd]) return -EBADF;
	FILE *f = current_task->files[fd];
	current_task->close_on_exec &= ~(1 << fd);
	current_task->files[fd] = 0;
	if (f->count && !(--f->count)) {
		close_fs(f->node);
		iput(f->node);
		free(f);
	}
	return 0;
}
Exemple #10
0
int exec_shebang(char * path, fs_node_t * file, int argc, char ** argv, char ** env, int interp) {
	/* Read MAX_LINE... */
	char tmp[100];
	read_fs(file, 0, 100, (unsigned char *)tmp); close_fs(file);
	char * cmd = (char *)&tmp[2];
	char * space_or_linefeed = strpbrk(cmd, " \n");
	char * arg = NULL;

	if (!space_or_linefeed) {
		debug_print(WARNING, "No space or linefeed found.");
		return -ENOEXEC;
	}

	if (*space_or_linefeed == ' ') {
		/* Oh lovely, an argument */
		*space_or_linefeed = '\0';
		space_or_linefeed++;
		arg = space_or_linefeed;
		space_or_linefeed = strpbrk(space_or_linefeed, "\n");
		if (!space_or_linefeed) {
			debug_print(WARNING, "Argument exceeded maximum length");
			return -ENOEXEC;
		}
	}
	*space_or_linefeed = '\0';

	char script[strlen(path)+1];
	memcpy(script, path, strlen(path)+1);

	unsigned int nargc = argc + (arg ? 2 : 1);
	char * args[nargc];
	args[0] = cmd;
	args[1] = arg ? arg : script;
	args[2] = arg ? script : NULL;
	args[3] = NULL;

	int j = arg ? 3 : 2;
	for (int i = 1; i < argc; ++i, ++j) {
		args[j] = argv[i];
	}
	args[j] = NULL;

	return exec(cmd, nargc, args, env);
}
Exemple #11
0
void onClose( GtkWidget *widget, gpointer data) {

  GtkTextBuffer *buffer;
  GtkTextIter start, end;
  //  GtkTreePath *path;

  if ( fs.isopen ) {
    // get the buffer
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (centre.texte));

    // empty the text area
    gtk_text_buffer_get_bounds ( buffer, &start, &end);
    gtk_text_buffer_delete ( buffer, &start, &end );

    // empty the tree
    gtk_tree_store_clear ( tree.treeStore );
    fs.isopen = 0;
    close_fs(fs.fd);
  }

}
Exemple #12
0
int exec_elf(char * path, fs_node_t * file, int argc, char ** argv, char ** env, int interp) {
	Elf32_Header header;

	read_fs(file, 0, sizeof(Elf32_Header), (uint8_t *)&header);

	if (header.e_ident[0] != ELFMAG0 ||
	    header.e_ident[1] != ELFMAG1 ||
	    header.e_ident[2] != ELFMAG2 ||
	    header.e_ident[3] != ELFMAG3) {
		debug_print(ERROR, "Not a valid ELF executable.");
		close_fs(file);
		return -1;
	}

	if (!interp) {
		current_process->name = strdup(path);
		current_process->cmdline = argv;
	}

	if (file->mask & 0x800) {
		debug_print(WARNING, "setuid binary executed [%s, uid:%d]", file->name, file->uid);
		current_process->user = file->uid;
	}

	for (uintptr_t x = 0; x < (uint32_t)header.e_phentsize * header.e_phnum; x += header.e_phentsize) {
		Elf32_Phdr phdr;
		read_fs(file, header.e_phoff + x, sizeof(Elf32_Phdr), (uint8_t *)&phdr);
		if (phdr.p_type == PT_DYNAMIC) {
			/* Dynamic */
			close_fs(file);

			/* Find interpreter? */
			debug_print(WARNING, "Dynamic executable");

			unsigned int nargc = argc + 3;
			char * args[nargc];
			args[0] = "ld.so";
			args[1] = "-e";
			args[2] = strdup(current_process->name);
			int j = 3;
			for (int i = 0; i < argc; ++i, ++j) {
				args[j] = argv[i];
			}
			args[j] = NULL;

			fs_node_t * file = kopen("/lib/ld.so",0);
			if (!file) return -1;

			return exec_elf(NULL, file, nargc, args, env, 1);
		}
	}

	uintptr_t entry = (uintptr_t)header.e_entry;
	uintptr_t base_addr = 0xFFFFFFFF;
	uintptr_t end_addr  = 0x0;

	for (uintptr_t x = 0; x < (uint32_t)header.e_phentsize * header.e_phnum; x += header.e_phentsize) {
		Elf32_Phdr phdr;
		read_fs(file, header.e_phoff + x, sizeof(Elf32_Phdr), (uint8_t *)&phdr);
		if (phdr.p_type == PT_LOAD) {
			if (phdr.p_vaddr < base_addr) {
				base_addr = phdr.p_vaddr;
			}
			if (phdr.p_memsz + phdr.p_vaddr > end_addr) {
				end_addr = phdr.p_memsz + phdr.p_vaddr;
			}
		}
	}

	current_process->image.entry = base_addr;
	current_process->image.size  = end_addr - base_addr;

	release_directory_for_exec(current_directory);
	invalidate_page_tables();


	for (uintptr_t x = 0; x < (uint32_t)header.e_phentsize * header.e_phnum; x += header.e_phentsize) {
		Elf32_Phdr phdr;
		read_fs(file, header.e_phoff + x, sizeof(Elf32_Phdr), (uint8_t *)&phdr);
		if (phdr.p_type == PT_LOAD) {
			for (uintptr_t i = phdr.p_vaddr; i < phdr.p_vaddr + phdr.p_memsz; i += 0x1000) {
				/* This doesn't care if we already allocated this page */
				alloc_frame(get_page(i, 1, current_directory), 0, 1);
				invalidate_tables_at(i);
			}
			IRQ_RES;
			read_fs(file, phdr.p_offset, phdr.p_filesz, (uint8_t *)phdr.p_vaddr);
			IRQ_OFF;
			size_t r = phdr.p_filesz;
			while (r < phdr.p_memsz) {
				*(char *)(phdr.p_vaddr + r) = 0;
				r++;
			}
		}
	}

	close_fs(file);

	for (uintptr_t stack_pointer = USER_STACK_BOTTOM; stack_pointer < USER_STACK_TOP; stack_pointer += 0x1000) {
		alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
		invalidate_tables_at(stack_pointer);
	}

	/* Collect arguments */
	int envc = 0;
	for (envc = 0; env[envc] != NULL; ++envc);

	/* Format auxv */
	Elf32_auxv auxv[] = {
		{256, 0xDEADBEEF},
		{0, 0}
	};
	int auxvc = 0;
	for (auxvc = 0; auxv[auxvc].id != 0; ++auxvc);
	auxvc++;

	uintptr_t heap = current_process->image.entry + current_process->image.size;
	while (heap & 0xFFF) heap++;
	alloc_frame(get_page(heap, 1, current_directory), 0, 1);
	invalidate_tables_at(heap);
	char ** argv_ = (char **)heap;
	heap += sizeof(char *) * (argc + 1);
	char ** env_ = (char **)heap;
	heap += sizeof(char *) * (envc + 1);
	void * auxv_ptr = (void *)heap;
	heap += sizeof(Elf32_auxv) * (auxvc);

	for (int i = 0; i < argc; ++i) {
		size_t size = strlen(argv[i]) * sizeof(char) + 1;
		for (uintptr_t x = heap; x < heap + size + 0x1000; x += 0x1000) {
			alloc_frame(get_page(x, 1, current_directory), 0, 1);
		}
		invalidate_tables_at(heap);
		argv_[i] = (char *)heap;
		memcpy((void *)heap, argv[i], size);
		heap += size;
	}
	/* Don't forget the NULL at the end of that... */
	argv_[argc] = 0;

	for (int i = 0; i < envc; ++i) {
		size_t size = strlen(env[i]) * sizeof(char) + 1;
		for (uintptr_t x = heap; x < heap + size + 0x1000; x += 0x1000) {
			alloc_frame(get_page(x, 1, current_directory), 0, 1);
		}
		invalidate_tables_at(heap);
		env_[i] = (char *)heap;
		memcpy((void *)heap, env[i], size);
		heap += size;
	}
	env_[envc] = 0;

	memcpy(auxv_ptr, auxv, sizeof(Elf32_auxv) * (auxvc));

	current_process->image.heap        = heap; /* heap end */
	current_process->image.heap_actual = heap + (0x1000 - heap % 0x1000);
	alloc_frame(get_page(current_process->image.heap_actual, 1, current_directory), 0, 1);
	invalidate_tables_at(current_process->image.heap_actual);
	current_process->image.user_stack  = USER_STACK_TOP;

	current_process->image.start = entry;

	/* Go go go */
	enter_user_jmp(entry, argc, argv_, USER_STACK_TOP);

	/* We should never reach this code */
	return -1;
}
Exemple #13
0
/**
 * Load and execute a static ELF binary.
 *
 * We make one assumption on the location the binary expects to be loaded
 * at: that it be outside of the kernel memory space.
 *
 * Arguments are passed to the stack of the user application so that they
 * can be read properly.
 *
 * TODO: Environment variables should be loaded somewhere.
 *
 * HACK: ELF verification isn't complete.
 *
 * @param path Path to the executable to attempt to execute.
 * @param argc Number of arguments (because I'm not counting for you)
 * @param argv Pointer to a string of arguments
 */
int
exec(
    char *  path, /* Path to the executable to run */
    int     argc, /* Argument count (ie, /bin/echo hello world = 3) */
    char ** argv, /* Argument strings (including executable path) */
    char ** env   /* Environmen variables */
) {

    /* Open the file */
    fs_node_t * file = kopen(path,0);
    if (!file) {
        /* Command not found */
        return 0;
    }
    /* Read in the binary contents */
    for (uintptr_t x = 0x30000000; x < 0x30000000 + file->length; x += 0x1000) {
        alloc_frame(get_page(x, 1, current_directory), 0, 1);
    }
    Elf32_Header * header = (Elf32_Header *)0x30000000; //(Elf32_Header *)malloc(file->length + 100);
    read_fs(file, 0, file->length, (uint8_t *)header);

    current_process->name = malloc(strlen(path) + 1);
    memcpy(current_process->name, path, strlen(path) + 1);

    /* Alright, we've read the binary, time to load the loadable sections */
    /* Verify the magic */
    if (	header->e_ident[0] != ELFMAG0 ||
            header->e_ident[1] != ELFMAG1 ||
            header->e_ident[2] != ELFMAG2 ||
            header->e_ident[3] != ELFMAG3) {
        /* What? This isn't an ELF... */
        kprintf("Fatal: Not a valid ELF executable.\n");
        for (uintptr_t x = 0x30000000; x < 0x30000000 + file->length; x += 0x1000) {
            free_frame(get_page(x, 0, current_directory));
        }
        close_fs(file);
        return -1;
    }

    /* Load the loadable segments from the binary */
    for (uintptr_t x = 0; x < (uint32_t)header->e_shentsize * header->e_shnum; x += header->e_shentsize) {
        /* read a section header */
        Elf32_Shdr * shdr = (Elf32_Shdr *)((uintptr_t)header + (header->e_shoff + x));
        if (shdr->sh_addr) {
            /* If this is a loadable section, load it up. */
            if (shdr->sh_addr < current_process->image.entry) {
                /* If this is the lowest entry point, store it for memory reasons */
                current_process->image.entry = shdr->sh_addr;
            }
            if (shdr->sh_addr + shdr->sh_size - current_process->image.entry > current_process->image.size) {
                /* We also store the total size of the memory region used by the application */
                current_process->image.size = shdr->sh_addr + shdr->sh_size - current_process->image.entry;
            }
            for (uintptr_t i = 0; i < shdr->sh_size + 0x2000; i += 0x1000) {
                /* This doesn't care if we already allocated this page */
                alloc_frame(get_page(shdr->sh_addr + i, 1, current_directory), 0, 1);
            }
            if (shdr->sh_type == SHT_NOBITS) {
                /* This is the .bss, zero it */
                memset((void *)(shdr->sh_addr), 0x0, shdr->sh_size);
            } else {
                /* Copy the section into memory */
                memcpy((void *)(shdr->sh_addr), (void *)((uintptr_t)header + shdr->sh_offset), shdr->sh_size);
            }
        }
    }

    /* Store the entry point to the code segment */
    uintptr_t entry = (uintptr_t)header->e_entry;

    /* Free the space we used for the ELF headers and files */
    for (uintptr_t x = 0x30000000; x < 0x30000000 + file->length; x += 0x1000) {
        free_frame(get_page(x, 0, current_directory));
    }
    close_fs(file);

    for (uintptr_t stack_pointer = USER_STACK_BOTTOM; stack_pointer < USER_STACK_TOP; stack_pointer += 0x1000) {
        alloc_frame(get_page(stack_pointer, 1, current_directory), 0, 1);
    }

    /* Collect arguments */
    int envc = 0;
    for (envc = 0; env[envc] != NULL; ++envc);

    /* Format auxv */
    Elf32_auxv auxv[] = {
        {256, 0xDEADBEEF},
        {0, 0}
    };
    int auxvc = 0;
    for (auxvc = 0; auxv[auxvc].id != 0; ++auxvc);

    uintptr_t heap = current_process->image.entry + current_process->image.size;
    alloc_frame(get_page(heap, 1, current_directory), 0, 1);
    char ** argv_ = (char **)heap;
    heap += sizeof(char *) * (argc + 1);
    char ** env_ = (char **)heap;
    heap += sizeof(char *) * (envc + 1);
    void * auxv_ptr = (void *)heap;
    heap += sizeof(Elf32_auxv) * (auxvc);

    for (int i = 0; i < argc; ++i) {
        alloc_frame(get_page(heap, 1, current_directory), 0, 1);
        argv_[i] = (char *)heap;
        memcpy((void *)heap, argv[i], strlen(argv[i]) * sizeof(char) + 1);
        heap += strlen(argv[i]) + 1;
    }
    /* Don't forget the NULL at the end of that... */
    argv_[argc] = 0;

    for (int i = 0; i < envc; ++i) {
        alloc_frame(get_page(heap, 1, current_directory), 0, 1);
        env_[i] = (char *)heap;
        memcpy((void *)heap, env[i], strlen(env[i]) * sizeof(char) + 1);
        heap += strlen(env[i]) + 1;
    }
    env_[envc] = 0;

    memcpy(auxv_ptr, auxv, sizeof(Elf32_auxv) * (auxvc));

    current_process->image.heap        = heap; /* heap end */
    current_process->image.heap_actual = heap + (0x1000 - heap % 0x1000);
    current_process->image.user_stack  = USER_STACK_TOP;
    while (current_process->fds->length < 3) {
        process_append_fd((process_t *)current_process, NULL);
    }

    current_process->image.start = entry;

    /* Go go go */
    enter_user_jmp(entry, argc, argv_, USER_STACK_TOP);

    /* We should never reach this code */
    return -1;
}
Exemple #14
0
static int sys_open(const char * file, int flags, int mode) {
	PTR_VALIDATE(file);
	debug_print(NOTICE, "open(%s) flags=0x%x; mode=0x%x", file, flags, mode);
	fs_node_t * node = kopen((char *)file, flags);

	int access_bits = 0;

	if (node && (flags & O_CREAT) && (flags & O_EXCL)) {
		close_fs(node);
		return -EEXIST;
	}

	if (!(flags & O_WRONLY) || (flags & O_RDWR)) {
		if (node && !has_permission(node, 04)) {
			debug_print(WARNING, "access denied (read, sys_open, file=%s)", file);
			close_fs(node);
			return -EACCES;
		} else {
			access_bits |= 01;
		}
	}

	if ((flags & O_RDWR) || (flags & O_WRONLY)) {
		if (node && !has_permission(node, 02)) {
			close_fs(node);
			return -EACCES;
		}
		if (node && (node->flags & FS_DIRECTORY)) {
			return -EISDIR;
		}
		if ((flags & O_RDWR) || (flags & O_WRONLY)) {
			/* truncate doesn't grant write permissions */
			access_bits |= 02;
		}
	}

	if (!node && (flags & O_CREAT)) {
		/* TODO check directory permissions */
		debug_print(NOTICE, "- file does not exist and create was requested.");
		/* Um, make one */
		int result = create_file_fs((char *)file, mode);
		if (!result) {
			node = kopen((char *)file, flags);
		} else {
			return result;
		}
	}

	if (node && (flags & O_DIRECTORY)) {
		if (!(node->flags & FS_DIRECTORY)) {
			return -ENOTDIR;
		}
	}

	if (node && (flags & O_TRUNC)) {
		if (!(access_bits & 02)) {
			close_fs(node);
			return -EINVAL;
		}
		truncate_fs(node);
	}

	if (!node) {
		return -ENOENT;
	}
	if (node && (flags & O_CREAT) && (node->flags & FS_DIRECTORY)) {
		close_fs(node);
		return -EISDIR;
	}
	int fd = process_append_fd((process_t *)current_process, node);
	FD_MODE(fd) = access_bits;
	if (flags & O_APPEND) {
		FD_OFFSET(fd) = node->length;
	} else {
		FD_OFFSET(fd) = 0;
	}
	debug_print(INFO, "[open] pid=%d %s -> %d", getpid(), file, fd);
	return fd;
}
Exemple #15
0
void onQuit(GtkWidget *pWidget, gpointer pData) {
  if ( fs.isopen ) {
    close_fs(fs.fd);
  }
  gtk_main_quit();
}