status_t vfs_get_info (int16_t fd, file_info_t * p_info) /* * ARGUMENTS * * fd : the file identifier * * p_info : a pointer to a file_info_t structure * * FUNCTION * Looks-up for the file corresponding to fd * If it exists, then calls the * file's get_info() function. * * RESULT * Fill-in the file_info_t structure. * * SOURCE */ { file_t file = NULL; status_t status = DNA_OK; watch (status_t) { ensure (fd >= 0 && fd < DNA_MAX_FILE, DNA_INVALID_FD); /* * Get the file associated to the fd. */ status = file_get (fd, & file); ensure (status == DNA_OK, status); /* * Call ioctl on the file. */ status = file -> vnode -> volume -> cmd -> get_info (file -> vnode -> volume -> data, file -> vnode -> data, file -> data, p_info); check (error, status == DNA_OK, status); /* * Release the file and return. */ status = file_put (fd); panic (status != DNA_OK); return DNA_OK; } rescue (error) { status = file_put (fd); panic (status != DNA_OK); leave; } }
int sys_attach_pty(int fd) { struct file *mf = file_get(fd); if(!mf) { return -EBADF; } if(MAJOR(mf->inode->phys_dev) != pty_major) { file_put(mf); return -EINVAL; } __pty_open(mf); file_put(mf); return 0; }
int sys_read(int fp, off_t pos, unsigned char *buf, size_t count) { if(!buf) return -EINVAL; struct file *f = file_get(fp); if(!f) return -EBADF; if(!(f->flags & _FREAD)) { file_put(f); return -EACCES; } int ret = fs_file_pread(f, pos, buf, count); file_put(f); return ret; }
int sys_openpty(int *master, int *slave, char *slavename, const struct termios *term, const struct winsize *win) { int num = atomic_fetch_add(&__pty_next_num, 1); char mname[32]; char sname[32]; snprintf(mname, 32, "/dev/ptym%d", num); snprintf(sname, 32, "/dev/ptys%d", num); sys_mknod(mname, S_IFCHR | 0666, GETDEV(pty_major, num)); sys_mknod(sname, S_IFCHR | 0666, GETDEV(pty_major, num)); int mfd = sys_open(mname, O_RDWR, 0); int sfd = sys_open(sname, O_RDWR, 0); if(mfd < 0 || sfd < 0) { sys_unlink(mname); sys_unlink(sname); return -ENOENT; } struct file *mf = file_get(mfd); struct file *sf = file_get(sfd); vfs_inode_get(mf->inode); vfs_inode_get(sf->inode); pty_create(mf->inode); sf->inode->devdata = mf->inode->devdata; struct pty *pty = mf->inode->devdata; assert(pty); pty->master = mf->inode; pty->slave = sf->inode; pty->num = num; if(term) memcpy(&pty->term, term, sizeof(*term)); if(win) memcpy(&pty->size, win, sizeof(*win)); file_put(mf); file_put(sf); if(slavename) strncpy(slavename, sname, 32); if(master) *master = mfd; if(slave) *slave = sfd; return 0; }
/* Dump character history to a file, which we assume is already open. */ void dump_history(ang_file *file) { size_t i; char buf[90]; /* We use either ascii or system-specific encoding */ int encoding = OPT(xchars_to_file) ? SYSTEM_SPECIFIC : ASCII; file_putf(file, "============================================================\n"); file_putf(file, " CHAR.\n"); file_putf(file, "| TURN | DEPTH |LEVEL| EVENT\n"); file_putf(file, "============================================================\n"); for (i = 0; i < (last_printable_item() + 1); i++) { /* Skip not-yet-IDd artifacts */ if (history_masked(i)) continue; strnfmt(buf, sizeof(buf), "%10d%7d\'%5d %s", history_list[i].turn, history_list[i].dlev * 50, history_list[i].clev, history_list[i].event); if (history_list[i].type & HISTORY_ARTIFACT_LOST) my_strcat(buf, " (LOST)", sizeof(buf)); x_file_putf(file, encoding, "%s", buf); file_put(file, "\n"); } return; }
/** * Hook function - dump a char_attr line to a file */ void dump_line_file(char_attr *this_line) { int x = 0; char_attr xa = this_line[0]; byte (*old_xchar_hook)(byte c) = Term->xchar_hook; char buf[2]; /* We use either ascii or system-specific encoding */ int encoding = OPT(xchars_to_file) ? SYSTEM_SPECIFIC : ASCII; /* Display the requested encoding -- ASCII or system-specific */ if (!OPT(xchars_to_file)) Term->xchar_hook = NULL; /* Dump the line */ while (xa.pchar != '\0') { /* Add the char/attr */ x_fprintf(dump_out_file, encoding, "%c", xa.pchar); /* Advance */ xa = this_line[++x]; } /* Return to standard display */ Term->xchar_hook = old_xchar_hook; /* Terminate the line */ buf[0] = '\n'; buf[1] = '\0'; file_put(dump_out_file, buf); }
int sys_write(int fp, off_t pos, unsigned char *buf, size_t count) { struct file *f = file_get(fp); if(!f) return -EBADF; if(!count || !buf) { file_put(f); return -EINVAL; } if(!(f->flags & _FWRITE)) { file_put(f); return -EACCES; } int ret = fs_file_pwrite(f, pos, buf, count); file_put(f); return ret; }
int ft_command(char *data, t_uenv *user, char *pwd) { int wt; char **param; if (data[0] == '\0') { send(user->cs, "Wrong command\n", 14, 0); send(user->cs, "ERROR\n", 6, 0); return (1); } param = ft_split_whitespaces(data); wt = 300; (void)pwd; if (ft_strcmp(param[0], "ls") == 0) { user = core(user, data); send(user->cs, "SUCCES\n", 7, 0); return (1); } else if (ft_strcmp(param[0], "cd") == 0) { ft_cd(&user, ft_strsplit(data, ' ')); //send(user->cs, ft_strjoin(user->pwd, "\n"), ft_strlen(user->pwd) + 1, 0); send(user->cs, "SUCCES\n", 7, 0); return (1); } else if (ft_strcmp(param[0], "get") == 0) { file_get(user, data); //send(user->cs, "SUCCES\n", 7, 0); return (1); } else if (ft_strcmp(param[0], "put") == 0) { file_put(user, param[1]); //send(user->cs, "SUCCES\n", 7, 0); return (1); } else if (ft_strcmp(param[0], "pwd") == 0 && param[1] == NULL) { send(user->cs, ft_strjoin(user->pwd, "\n"), ft_strlen(user->pwd) + 1, 0); send(user->cs, "SUCCES\n", 7, 0); return (1); } else if (ft_strcmp(param[0], "quit") == 0 && param[1] == NULL) { send(user->cs, "Exit\n", 5, 0); close(user->cs); return (0); } else { send(user->cs, "Wrong command\n", 14, 0); send(user->cs, "ERROR\n", 6, 0); } return (1); }
int sys_getdents(int fd, struct dirent_posix *dirs, unsigned int count) { struct file *f = file_get(fd); if(!f) return -EBADF; unsigned nex; if(!vfs_inode_check_permissions(f->inode, MAY_READ, 0)) { file_put(f); return -EACCES; } rwlock_acquire(&f->inode->lock, RWL_READER); int r = fs_callback_inode_getdents(f->inode, f->pos, dirs, count, &nex); rwlock_release(&f->inode->lock, RWL_READER); f->pos = nex; file_put(f); return r; }
int sys_posix_fsstat(int fd, struct posix_statfs *sb) { struct file *f = file_get(fd); if(!f) return -EBADF; struct inode *i = f->inode; int r = fs_callback_fs_stat(i->filesystem, sb); file_put(f); return r; }
int sys_isatty(int f) { struct file *file = file_get(f); if(!file) return -EBADF; int ret = MAJOR(file->inode->phys_dev) == pty_major; file_put(file); return ret; }
/** * Append a formatted line of text to the end of file 'f'. * * file_vputf() is the va_list version. It returns TRUE if the write was * successful and FALSE otherwise. */ bool file_vputf(ang_file *f, const char *fmt, va_list vp) { char buf[1024]; if (!f) return FALSE; (void)vstrnfmt(buf, sizeof(buf), fmt, vp); return file_put(f, buf); }
int sys_fstat(int fp, struct stat *sb) { if(!sb) return -EINVAL; struct file *f = file_get(fp); if(!f) return -EBADF; do_stat(f->inode, sb); file_put(f); return 0; }
int sys_writepos(int fp, unsigned char *buf, size_t count) { struct file *f = file_get(fp); if(!f) return -EBADF; if(!count || !buf) { file_put(f); return -EINVAL; } if(!(f->flags & _FWRITE)) { file_put(f); return -EACCES; } if(f->flags & _FAPPEND) f->pos = f->inode->length; int ret = fs_file_write(f, buf, count); file_put(f); return ret; }
/* * Append a formatted line of text to the end of file 'f'. */ bool file_putf(ang_file *f, const char *fmt, ...) { char buf[1024]; va_list vp; va_start(vp, fmt); (void)vstrnfmt(buf, sizeof(buf), fmt, vp); va_end(vp); return file_put(f, buf); }
static int gpio_write(int gpio, int value) { int ret; char tmp[256]; if ((ret = check_exported(gpio))) return ret; sprintf(tmp, "/sys/class/gpio%d/value", gpio); if (0 < file_put(tmp, value ? "1" : "0")) return 0; return -EIO; }
static int gpio_out(int gpio) { int ret; char tmp[256]; if ((ret = check_exported(gpio))) return ret; sprintf(tmp, "/sys/class/gpio%d/direction", gpio); if (0 < file_put(tmp, "out")) return 0; return -EIO; }
static int gpio_export(int gpio) { char tmp[128]; sprintf(tmp, "/sys/class/gpio/gpio%d", gpio); if (0 == access(tmp, F_OK)) { slog(0, SLOG_WARN, "sysfsgpio: GPIO %d already exported", gpio); return 0; } sprintf(tmp, "%d", gpio); if (0 < file_put("/sys/class/gpio/export", tmp)) return 0; return -1; }
int main() { Cmix_file::enable_ft_support(); xcc_dirs::load_from_registry(); string dir = xcc_dirs::get_dir(game_dune2); Cxd2_files files; if (files.load(dir)) return 1; file_put(xcc_dirs::get_data_dir() + "xd2 files.xif", files.save().vdata()); shared_data exe = file_get(dir + "dune2.exe"); if (!exe.size()) return 1; const char* e = reinterpret_cast<const char*>(exe.data()); auto bt = reinterpret_cast<const t_building_type*>(&exe[194010]); for (auto& i : boost::make_iterator_range(bt, bt + 19)) { ofstream("../xd2 be/dune/objects/" + to_lower_copy(string(e + 229504 + i.name)) + ".ini") << "cameo = " << i.cameo_shp_index << endl << "class = structure" << endl << "cost = " << i.cost << endl << "cx = " << (i.size == 0 || i.size == 2 ? 1 : i.size == 1 || i.size == 3 || i.size == 4 ? 2 : 3) << endl << "cy = " << (i.size == 0 || i.size == 1 ? 1 : i.size == 2 || i.size == 3 || i.size == 5 ? 2 : 3) << endl << "icon = " << i.icon_index << endl << "power = " << i.power_in << endl << "sight = " << i.sight << endl << "strength = " << i.strength << endl << "techlevel = " << i.techlevel << endl << "wsa = " << e + 229504 + i.wsa << endl ; } auto ut = reinterpret_cast<const t_unit_type*>(&exe[195840]); for (auto& i : boost::make_iterator_range(ut, ut + 27)) { ofstream("../xd2 be/dune/objects/" + to_lower_copy(string(e + 229504 + i.name)) + ".ini") << "body = " << i.body_shp_index << endl << "cameo = " << i.cameo_shp_index << endl << "cost = " << i.cost << endl << "sight = " << i.sight << endl << "speed = " << i.speed << endl << "strength = " << i.strength << endl << "turret = " << i.turret_shp_index << endl << "wsa = " << e + 229504 + i.wsa << endl ; } return 0; }
/* * Format and translate a string, then print it out to file. */ bool x_file_putf(ang_file *f, const char *fmt, ...) { va_list vp; char buf[1024]; /* Begin the Varargs Stuff */ va_start(vp, fmt); /* Format the args, save the length */ (void)vstrnfmt(buf, sizeof(buf), fmt, vp); /* End the Varargs Stuff */ va_end(vp); return file_put(f, buf); }
/** * Format and translate a string, then print it out to file. */ void x_fprintf(ang_file *f, int encoding, const char *fmt, ...) { va_list vp; char buf[1024]; /* Begin the Varargs Stuff */ va_start(vp, fmt); /* Format the args, save the length */ (void)vstrnfmt(buf, sizeof(buf), fmt, vp); /* End the Varargs Stuff */ va_end(vp); /* Translate */ xstr_trans(buf, encoding); file_put(f, buf); }
int do_exec(char *path, char **argv, char **env, int shebanged /* oh my */) { unsigned int i=0; addr_t end, eip; unsigned int argc=0, envc=0; char **backup_argv=0, **backup_env=0; /* Sanity */ if(!path || !*path) return -EINVAL; /* Load the file, and make sure that it is valid and accessible */ if(EXEC_LOG == 2) printk(0, "[%d]: Checking executable file (%s)\n", current_process->pid, path); struct file *efil; int err_open; efil = fs_file_open(path, _FREAD, 0, &err_open); if(!efil) return err_open; /* are we allowed to execute it? */ if(!vfs_inode_check_permissions(efil->inode, MAY_EXEC, 0)) { file_put(efil); return -EACCES; } /* is it a valid elf? */ int header_size = 0; #if CONFIG_ARCH == TYPE_ARCH_X86_64 header_size = sizeof(elf64_header_t); #elif CONFIG_ARCH == TYPE_ARCH_X86 header_size = sizeof(elf32_header_t); #endif /* read in the ELF header, and check if it's a shebang */ if(header_size < 2) header_size = 2; unsigned char mem[header_size]; fs_file_pread(efil, 0, mem, header_size); if(__is_shebang(mem)) return loader_do_shebang(efil, argv, env); int other_bitsize=0; if(!is_valid_elf(mem, 2) && !other_bitsize) { file_put(efil); return -ENOEXEC; } if(EXEC_LOG == 2) printk(0, "[%d]: Copy data\n", current_process->pid); /* okay, lets back up argv and env so that we can * clear out the address space and not lose data... * If this call if coming from a shebang, then we don't check the pointers, * since they won't be from userspace */ size_t total_args_len = 0; if((shebanged || mm_is_valid_user_pointer(SYS_EXECVE, argv, 0)) && argv) { while((shebanged || mm_is_valid_user_pointer(SYS_EXECVE, argv[argc], 0)) && argv[argc] && *argv[argc]) argc++; backup_argv = (char **)kmalloc(sizeof(addr_t) * argc); for(i=0;i<argc;i++) { backup_argv[i] = (char *)kmalloc(strlen(argv[i]) + 1); _strcpy(backup_argv[i], argv[i]); total_args_len += strlen(argv[i])+1 + sizeof(char *); } } if((shebanged || mm_is_valid_user_pointer(SYS_EXECVE, env, 0)) && env) { while((shebanged || mm_is_valid_user_pointer(SYS_EXECVE, env[envc], 0)) && env[envc] && *env[envc]) envc++; backup_env = (char **)kmalloc(sizeof(addr_t) * envc); for(i=0;i<envc;i++) { backup_env[i] = (char *)kmalloc(strlen(env[i]) + 1); _strcpy(backup_env[i], env[i]); total_args_len += strlen(env[i])+1 + sizeof(char *); } } total_args_len += 2 * sizeof(char *); /* and the path too! */ char *path_backup = (char *)kmalloc(strlen(path) + 1); _strcpy((char *)path_backup, path); path = path_backup; /* Preexec - This is the point of no return. Here we close out unneeded * file descs, free up the page directory and clear up the resources * of the task */ if(EXEC_LOG) printk(0, "Executing (p%dt%d, cpu %d, tty %d): %s\n", current_process->pid, current_thread->tid, current_thread->cpu->knum, current_process->pty ? current_process->pty->num : 0, path); preexec(); /* load in the new image */ strncpy((char *)current_process->command, path, 128); if(!loader_parse_elf_executable(mem, efil, &eip, &end)) eip=0; /* do setuid and setgid */ if(efil->inode->mode & S_ISUID) { current_process->effective_uid = efil->inode->uid; } if(efil->inode->mode & S_ISGID) { current_process->effective_gid = efil->inode->gid; } /* we don't need the file anymore, close it out */ file_put(efil); file_close_cloexec(); if(!eip) { printk(5, "[exec]: Tried to execute an invalid ELF file!\n"); free_dp(backup_argv, argc); free_dp(backup_env, envc); kfree(path); tm_thread_exit(0); } if(EXEC_LOG == 2) printk(0, "[%d]: Updating task values\n", current_process->pid); /* Setup the task with the proper values (libc malloc stack) */ addr_t end_l = end; end = ((end-1)&PAGE_MASK) + PAGE_SIZE; total_args_len += PAGE_SIZE; /* now we need to copy back the args and env into userspace * writeable memory...yippie. */ addr_t args_start = end + PAGE_SIZE; addr_t env_start = args_start; addr_t alen = 0; mm_mmap(end, total_args_len, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0, 0); if(backup_argv) { memcpy((void *)args_start, backup_argv, sizeof(addr_t) * argc); alen += sizeof(addr_t) * argc; *(addr_t *)(args_start + alen) = 0; /* set last argument value to zero */ alen += sizeof(addr_t); argv = (char **)args_start; for(i=0;i<argc;i++) { char *old = argv[i]; char *new = (char *)(args_start+alen); unsigned len = strlen(old) + 4; argv[i] = new; _strcpy(new, old); kfree(old); alen += len; } kfree(backup_argv); } env_start = args_start + alen; alen = 0; if(backup_env) { memcpy((void *)env_start, backup_env, sizeof(addr_t) * envc); alen += sizeof(addr_t) * envc; *(addr_t *)(env_start + alen) = 0; /* set last argument value to zero */ alen += sizeof(addr_t); env = (char **)env_start; for(i=0;i<envc;i++) { char *old = env[i]; char *new = (char *)(env_start+alen); unsigned len = strlen(old) + 1; env[i] = new; _strcpy(new, old); kfree(old); alen += len; } kfree(backup_env); } end = (env_start + alen) & PAGE_MASK; current_process->env = env; current_process->argv = argv; kfree(path); /* set the heap locations, and map in the start */ current_process->heap_start = current_process->heap_end = end + PAGE_SIZE*2; addr_t ret = mm_mmap(end + PAGE_SIZE, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0, 0); /* now, we just need to deal with the syscall return stuff. When the syscall * returns, it'll just jump into the entry point of the new process */ tm_thread_lower_flag(current_thread, THREAD_SCHEDULE); /* the kernel cares if it has executed something or not */ if(!(kernel_state_flags & KSF_HAVEEXECED)) set_ksf(KSF_HAVEEXECED); arch_loader_exec_initializer(argc, eip); if(EXEC_LOG == 2) printk(0, "[%d]: Performing call\n", current_process->pid); return 0; }