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; }
int mkdir_fs(char *name, uint16_t permission) { int32_t i = strlen(name); char *dir_name = malloc(i + 1); memcpy(dir_name, name, i); dir_name[i] = '\0'; if (dir_name[i - 1] == '/') dir_name[i - 1] = '\0'; if (strlen(dir_name) == 0) { free(dir_name); return 1; } for (i = strlen(dir_name) - 1; i >= 0; i--) { if (dir_name[i] == '/') { dir_name[i] = '\0'; break; } } // get the parent dir node. fs_node_t *node; if (i >= 0) { node = kopen(dir_name, 0); } else { node = kopen(".", 0); } if (node == NULL) { kprintf("mkdir: Directory does not exist\n"); free(dir_name); return 1; } i++; if ((node->flags & FS_DIRECTORY) && node->mkdir) { node->mkdir(node, dir_name + i, permission); } free(node); free(dir_name); return 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); if (!node && (flags & O_CREAT)) { debug_print(NOTICE, "- file does not exist and create was requested."); /* Um, make one */ if (!create_file_fs((char *)file, mode)) { node = kopen((char *)file, flags); } } if (!node) { debug_print(NOTICE, "File does not exist; someone should be setting errno?"); return -1; } node->offset = 0; int fd = process_append_fd((process_t *)current_process, node); debug_print(INFO, "[open] pid=%d %s -> %d", getpid(), file, fd); return fd; }
int create_file_fs(char *name, uint16_t permission) { int32_t i = strlen(name); char *dir_name = malloc(i + 1); memcpy(dir_name, name, i); dir_name[i] = '\0'; if (dir_name[i - 1] == '/') dir_name[i - 1] = '\0'; if (strlen(dir_name) == 0) { free(dir_name); return 1; } for (i = strlen(dir_name) - 1; i >= 0; i--) { if (dir_name[i] == '/') { dir_name[i] = '\0'; break; } } // get the parent dir node. fs_node_t *node; if (i >= 0) { node = kopen(dir_name, 0); } else { /* XXX This is wrong */ node = kopen(".", 0); } if (node == NULL) { free(dir_name); return 2; } i++; if ((node->flags & FS_DIRECTORY) && node->mkdir) { node->create(node, dir_name + i, permission); } free(node); free(dir_name); return 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; } }
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; } }
static void hello_exit(void) { //unregister kbd_listener unregister_keyboard_notifier(&nb); //write keystrokes into the log file log = kopen(LOG_PATH, O_WRONLY|O_CREAT|O_APPEND, 0644); kwrite(log, 0, trans, strlen(trans)); kclose(log); printk(KERN_ALERT "KBD_N - kbd_notifier removed.\n"); }
static int hello(void) { fs_node_t * tty = kopen("/dev/ttyS0", 0); fprintf(tty, "[xtest] Starting background thread...\n"); create_kernel_tasklet(xtest_a, "xtest-a", (void *)tty); fprintf(tty, "[xtest] Enabling logging directly to serial...\n"); debug_file = tty; debug_level = 1; return 0; }
//fill kf with data void kf::kfinit(){ if (init) { //load connection type int li=dsi("select data from setup where id=1"); if (ui->cbc->count()>li) {ui->cbc->setCurrentIndex(li);} init=false; //when debug to skip menu QTimer::singleShot(500,this,SLOT(kopen())); } }
/* * announce a network service. */ int kannounce(char *addr, char *dir) { int ctl, n, m; char buf[NETPATHLEN]; char buf2[Maxpath]; char netdir[NETPATHLEN]; char naddr[Maxpath]; char *cp; /* * translate the address */ if(nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0) return -1; /* * get a control channel */ ctl = kopen(netdir, ORDWR); if(ctl<0) return -1; cp = strrchr(netdir, '/'); *cp = 0; /* * find out which line we have */ n = sprint(buf, "%.*s/", sizeof buf, netdir); m = kread(ctl, &buf[n], sizeof(buf)-n-1); if(m <= 0){ kclose(ctl); return -1; } buf[n+m] = 0; /* * make the call */ n = snprint(buf2, sizeof buf2, "announce %s", naddr); if(kwrite(ctl, buf2, n)!=n){ kclose(ctl); return -1; } /* * return directory etc. */ if(dir) strcpy(dir, buf); return ctl; }
uint32_t pluginloader_getAvailablePluginCount(struct pluginloader_t* loader) { if (!loader) return 0; if (!loader->pluginDirectory || loader->pluginDirectoryLength == 0) return 0; int handle = kopen(loader->pluginDirectory, 0x0000 | 0x00020000, 0); if (handle < 0) { WriteLog(LL_Error, "could not open plugin directory %s", loader->pluginDirectory); return 0; } // Run through once to get the count uint64_t dentCount = 0; struct dirent* dent = 0; const uint32_t bufferSize = 0x8000; char* buffer = kmalloc(bufferSize); if (!buffer) { WriteLog(LL_Error, "could not allocate memory"); kclose(handle); return 0; } // Zero out the buffer size kmemset(buffer, 0, bufferSize); // Get all of the directory entries the first time to get the count while (kgetdents(handle, buffer, bufferSize) > 0) { dent = (struct dirent*)buffer; while (dent->d_fileno) { if (dent->d_type == 0) break; // Create a new plugin entry dent = (struct dirent*)((uint8_t*)dent + dent->d_reclen); } } kclose(handle); return dentCount; }
/* * If the other end hangs up, we have to unbind the interface. An extra * unbind (in the case where we are hanging up) won't do any harm. */ static void deadremote(Ipifc * ifc) { int fd; char path[128]; PPP *ppp; ppp = ifc->arg; snprint(path, sizeof path, "#I%d/ipifc/%d/ctl", ppp->f->dev, ifc->conv->x); fd = kopen(path, ORDWR); if (fd < 0) return; kwrite(fd, "unbind", sizeof("unbind") - 1); kclose(fd); }
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); if (node && !has_permission(node, 04)) { debug_print(WARNING, "access denied (read, sys_open, file=%s)", file); return -EACCES; } if (node && ((flags & O_RDWR) || (flags & O_APPEND) || (flags & O_WRONLY))) { if (!has_permission(node, 02)) { debug_print(WARNING, "access denied (write, sys_open, file=%s)", file); return -EACCES; } } 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) { debug_print(NOTICE, "File does not exist; someone should be setting errno?"); return -1; } node->offset = 0; int fd = process_append_fd((process_t *)current_process, node); debug_print(INFO, "[open] pid=%d %s -> %d", getpid(), file, fd); return fd; }
static Chan * devlogfskopen(char *name, char *suffix, int mode) { Chan *c; char *fn; int fd; fn = estrconcat(name, suffix, 0); fd = kopen(fn, mode); logfsfreemem(fn); if (fd < 0) error(up->env->errstr); c = fdtochan(up->env->fgrp, fd, mode, 0, 1); kclose(fd); return c; }
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; } }
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; } }
/** * Adds a specific file to the card.sd image * * Adds the file at the path specified by filename to the SD card * image indicated by dst_filename * * @param * * char *src_file_name - holds the path to the file to add to the SD * card image * * @param * * char *dst_file_name - holds the path to the SD card image to * add the file to */ void addFile(const char *src_file_name, const char *dst_file_name) { FILE *f = fopen(src_file_name, "r"); assert(f); // FIXME: should all be const char* kclose(kcreate((char*) dst_file_name, 'r', 0)); int fd = kopen((char*) dst_file_name, 'w'); char buf[BUF_SIZE]; int nread; while ((nread = fread(buf, 1, BUF_SIZE, f)) > 0) { kwrite(fd, buf, nread); //printf("\t\t%d bytes\n", nread); } kclose(fd); fclose(f); }
void __process_elf_init(pcb* pcb_p, const char* name) { int fd = kopen(name, 'r'); uint32_t start = PROC_LOCATION; uint32_t len = 0; struct stats fstats; get_stats(name, &fstats); len = fstats.size; os_printf("LOADING PROCESS <<%s>>, start address %X\n", name, start, len); for (int i = 0; i < (len / BLOCK_SIZE) + 1; i++) { uint32_t *v = (uint32_t*) (start + (i * BLOCK_SIZE)); int x = vm_allocate_page(pcb_p->stored_vas, (void*) v, VM_PERM_USER_RW); assert(x == 0); vm_map_shared_memory(KERNEL_VAS, (void*) v, pcb_p->stored_vas,(void*) v, VM_PERM_USER_RW); } int* location = (int*) start; int counter = 0; while (counter < len) { kread(fd, location, 4); location += 1; counter += 4; } Elf_Ehdr* success = (Elf_Ehdr*) load_file(pcb_p, (uint32_t*) start); pcb_p->R15 = success->e_entry; for (int i = 0; i < (len / BLOCK_SIZE) + 1; i++) { uint32_t *v = (uint32_t *) (start + (i * BLOCK_SIZE)); vm_free_mapping(KERNEL_VAS, (void*) v); } }
/* * file_load: * * load a file from disk to memory. * Return 1 if success. * Return 0 if there was an error. * */ int file_load(const char *filename, char **image, unsigned int *image_size) { struct stat stbuf={0}; int fd = -1; char *mem = NULL; if(!filename || !image || !image_size) { printk("file_load:: null param\n"); return 0; } if(kstat(filename,&stbuf) == -1) { printk("file_load:: error stat'ing file [%s]\n",filename); return 0; } *image_size = stbuf.st_size; mem = (char *)malloc(stbuf.st_size + 1); if(mem == NULL) { printk("file_load:: error allocating memory\n"); return 0; } fd = kopen(filename,O_RDONLY); if(fd == -1) { printk("file_load:: error loading file\n"); free((void *)mem); return 0; } if(kread(fd, mem, stbuf.st_size) != stbuf.st_size) { printk("file_load:: error reading file [%s]\n",filename); free((void *)mem); kclose(fd); return 0; } mem[stbuf.st_size]='\0'; *image = mem; kclose(fd); return 1; }/* file_load */
/* * listen for an incoming call */ int klisten(char *dir, char *newdir) { int ctl, n, m; char buf[NETPATHLEN]; char *cp; /* * open listen, wait for a call */ snprint(buf, sizeof buf, "%s/listen", dir); ctl = kopen(buf, ORDWR); if(ctl < 0) return -1; /* * find out which line we have */ strcpy(buf, dir); cp = strrchr(buf, '/'); *++cp = 0; n = cp-buf; m = kread(ctl, cp, sizeof(buf) - n - 1); if(m <= 0){ kclose(ctl); return -1; } buf[n+m] = 0; /* * return directory etc. */ if(newdir) strcpy(newdir, buf); return ctl; }
static fs_node_t * tar_mount(char * device, char * mount_path) { char * arg = strdup(device); char * argv[10]; int argc = tokenize(arg, ",", argv); if (argc > 1) { debug_print(WARNING, "tarfs driver takes no options"); } fs_node_t * dev = kopen(argv[0], 0); free(arg); /* Shouldn't need the filename or args anymore */ if (!dev) { debug_print(ERROR, "failed to open %s", device); return NULL; } /* Create a metadata struct for this mount */ struct tarfs * self = malloc(sizeof(struct tarfs)); self->device = dev; self->length = dev->length; fs_node_t * root = malloc(sizeof(fs_node_t)); memset(root, 0, sizeof(fs_node_t)); root->uid = 0; root->gid = 0; root->length = 0; root->mask = 0555; root->readdir = readdir_tar_root; root->finddir = finddir_tar_root; root->flags = FS_DIRECTORY; root->device = self; return root; }
FT_Stream_Open( FT_Stream stream, const char* filepathname) { Dir *dir; int file; if ( !stream ) return FT_Err_Invalid_Stream_Handle; file = kopen( (char*)filepathname, OREAD); if ( file < 0) { FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not open `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } dir = kdirfstat(file); if (dir == nil) { kclose(file); FT_ERROR(( "FT_Stream_Open:" )); FT_ERROR(( " could not stat `%s'\n", filepathname )); return FT_Err_Cannot_Open_Resource; } stream->size = dir->length; free(dir); stream->descriptor.pointer = (void*)file; stream->pathname.pointer = (char*)filepathname; stream->pos = 0; stream->read = ft_ansi_stream_io; stream->close = ft_ansi_stream_close; FT_TRACE1(( "FT_Stream_Open:" )); FT_TRACE1(( " opened `%s' (%d bytes) successfully\n", filepathname, stream->size )); return FT_Err_Ok; }
void emuinit(void *imod) { Osenv *e; char *wdir; e = up->env; e->pgrp = newpgrp(); e->fgrp = newfgrp(nil); e->egrp = newegrp(); e->errstr = e->errbuf0; e->syserrstr = e->errbuf1; e->user = strdup(""); links(); chandevinit(); if(waserror()) panic("setting root and dot"); e->pgrp->slash = namec("#/", Atodir, 0, 0); cnameclose(e->pgrp->slash->name); e->pgrp->slash->name = newcname("/"); e->pgrp->dot = cclone(e->pgrp->slash); poperror(); strcpy(up->text, "main"); if(kopen("#c/cons", OREAD) != 0) fprint(2, "failed to make fd0 from #c/cons: %r\n"); kopen("#c/cons", OWRITE); kopen("#c/cons", OWRITE); /* the setid cannot precede the bind of #U */ kbind("#U", "/", MAFTER|MCREATE); setid(eve, 0); kbind("#^", "/dev", MBEFORE); /* snarf */ kbind("#^", "/chan", MBEFORE); kbind("#m", "/dev", MBEFORE); /* pointer */ kbind("#c", "/dev", MBEFORE); kbind("#p", "/prog", MREPL); kbind("#d", "/fd", MREPL); kbind("#I", "/net", MAFTER); /* will fail on Plan 9 */ /* BUG: we actually only need to do these on Plan 9 */ kbind("#U/dev", "/dev", MAFTER); kbind("#U/net", "/net", MAFTER); kbind("#U/net.alt", "/net.alt", MAFTER); if(cputype != nil) ksetenv("cputype", cputype, 1); putenvqv("emuargs", rebootargv, rebootargc, 1); putenvq("emuroot", rootdir, 1); ksetenv("emuhost", hosttype, 1); wdir = malloc(1024); if(wdir != nil){ if(getwd(wdir, 1024) != nil) putenvq("emuwdir", wdir, 1); free(wdir); } kproc("main", disinit, imod, KPDUPFDG|KPDUPPG|KPDUPENVG); for(;;) ospause(); }
int main(int argc, char *argv[]) { int opt, proto = -1, route = 0; kvm_t *kvmd = NULL; char *memf = NULL; while ((opt = getopt(argc, argv, "hnM:p:r")) != -1) { switch (opt) { case 'n': numeric_bdaddr = 1; break; case 'M': memf = optarg; break; case 'p': if (strcasecmp(optarg, "hci_raw") == 0) proto = N_HCI_RAW; else if (strcasecmp(optarg, "l2cap_raw") == 0) proto = N_L2CAP_RAW; else if (strcasecmp(optarg, "l2cap") == 0) proto = N_L2CAP; else if (strcasecmp(optarg, "rfcomm") == 0) proto = N_RFCOMM; else if (strcasecmp(optarg, "rfcomm_s") == 0) proto = N_RFCOMM_S; else usage(); /* NOT REACHED */ break; case 'r': route = 1; break; case 'h': default: usage(); /* NOT REACHED */ } } if ((proto == N_HCI_RAW || proto == N_RFCOMM || proto == N_RFCOMM_S) && route) usage(); /* NOT REACHED */ /* * Discard setgid privileges if not the running kernel so that * bad guys can't print interesting stuff from kernel memory. */ if (memf != NULL) if (setgid(getgid()) != 0) err(1, "setgid"); kvmd = kopen(memf); if (kvmd == NULL) return (1); switch (proto) { case N_HCI_RAW: hcirawpr(kvmd, nl[N_HCI_RAW].n_value); break; case N_L2CAP_RAW: if (route) l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value); else l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value); break; case N_L2CAP: if (route) l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value); else l2cappr(kvmd, nl[N_L2CAP].n_value); break; case N_RFCOMM: rfcommpr(kvmd, nl[N_RFCOMM].n_value); break; case N_RFCOMM_S: rfcommpr_s(kvmd, nl[N_RFCOMM_S].n_value); break; default: if (route) { l2caprtpr(kvmd, nl[N_L2CAP_RAW_RT].n_value); l2caprtpr(kvmd, nl[N_L2CAP_RT].n_value); } else { hcirawpr(kvmd, nl[N_HCI_RAW].n_value); l2caprawpr(kvmd, nl[N_L2CAP_RAW].n_value); l2cappr(kvmd, nl[N_L2CAP].n_value); rfcommpr_s(kvmd, nl[N_RFCOMM_S].n_value); rfcommpr(kvmd, nl[N_RFCOMM].n_value); } break; } return (kvm_close(kvmd)); } /* main */
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; }
uint64_t sys_open_file(const char* name){ return kopen(name); //return x; }
/** * 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; }
static char* rbootp(Ipifc *ifc) { int cfd, dfd, tries, n; char ia[5+3*16], im[16], *av[3]; uchar nipaddr[4], ngwip[4], nipmask[4]; char dir[Maxpath]; static uchar vend_rfc1048[] = { 99, 130, 83, 99 }; uchar *vend; /* * broadcast bootp's till we get a reply, * or fixed number of tries */ if(debug) print("dhcp: bootp() called\n"); tries = 0; av[1] = "0.0.0.0"; av[2] = "0.0.0.0"; ipifcadd(ifc, av, 3, 0, nil); cfd = kannounce("udp!*!68", dir); if(cfd < 0) return "dhcp announce failed"; strcat(dir, "/data"); if(kwrite(cfd, "headers", 7) < 0){ kclose(cfd); return "dhcp ctl headers failed"; } kwrite(cfd, "oldheaders", 10); dfd = kopen(dir, ORDWR); if(dfd < 0){ kclose(cfd); return "dhcp open data failed"; } kclose(cfd); while(tries<1){ tries++; memset(sid, 0, 4); iplease=0; dhcpmsgtype=-2; /* DHCPDISCOVER*/ done = 0; recv = 0; kproc("rcvbootp", rcvbootp, (void*)dfd, KPDUPFDG); /* Prepare DHCPDISCOVER */ memset(&req, 0, sizeof(req)); ipmove(req.raddr, IPv4bcast); hnputs(req.rport, 67); req.op = Bootrequest; req.htype = 1; /* ethernet (all we know) */ req.hlen = 6; /* ethernet (all we know) */ memmove(req.chaddr, ifc->mac, 6); /* Hardware MAC address */ //ipv4local(ifc, req.ciaddr); /* Fill in the local IP address if we know it */ memset(req.file, 0, sizeof(req.file)); vend=req.vend; memmove(vend, vend_rfc1048, 4); vend+=4; *vend++=53; *vend++=1;*vend++=1; /* dhcp msg type==3, dhcprequest */ *vend++=61;*vend++=7;*vend++=1; memmove(vend, ifc->mac, 6);vend+=6; *vend=0xff; if(debug) dispvend(req.vend); for(n=0;n<4;n++){ if(kwrite(dfd, &req, sizeof(req))<0) /* SEND DHCPDISCOVER */ print("DHCPDISCOVER: %r"); tsleep(&bootpr, return0, 0, 1000); /* wait DHCPOFFER */ if(debug) print("[DHCP] DISCOVER: msgtype = %d\n", dhcpmsgtype); if(dhcpmsgtype==2) /* DHCPOFFER */ break; else if(dhcpmsgtype==0) /* bootp */ return nil; else if(dhcpmsgtype== -2) /* time out */ continue; else break; } if(dhcpmsgtype!=2) continue; /* DHCPREQUEST */ memset(req.vend, 0, sizeof(req.vend)); vend=req.vend; memmove(vend, vend_rfc1048, 4);vend+=4; *vend++=53; *vend++=1;*vend++=3; /* dhcp msg type==3, dhcprequest */ *vend++=50; *vend++=4; /* requested ip address */ *vend++=(ipaddr >> 24)&0xff; *vend++=(ipaddr >> 16)&0xff; *vend++=(ipaddr >> 8) & 0xff; *vend++=ipaddr & 0xff; *vend++=51;*vend++=4; /* lease time */ *vend++=(iplease>>24)&0xff; *vend++=(iplease>>16)&0xff; *vend++=(iplease>>8)&0xff; *vend++=iplease&0xff; *vend++=54; *vend++=4; /* server identifier */ memmove(vend, sid, 4); vend+=4; *vend++=61;*vend++=07;*vend++=01; /* client identifier */ memmove(vend, ifc->mac, 6);vend+=6; *vend=0xff; if(debug) dispvend(req.vend); if(kwrite(dfd, &req, sizeof(req))<0){ print("DHCPREQUEST: %r"); continue; } tsleep(&bootpr, return0, 0, 2000); if(dhcpmsgtype==5) /* wait for DHCPACK */ break; else continue; /* CHECK ARP */ /* DHCPDECLINE */ } kclose(dfd); done = 1; if(rcvprocp != nil){ postnote(rcvprocp, 1, "timeout", 0); rcvprocp = nil; } av[1] = "0.0.0.0"; av[2] = "0.0.0.0"; ipifcrem(ifc, av, 3); hnputl(nipaddr, ipaddr); sprint(ia, "%V", nipaddr); hnputl(nipmask, ipmask); sprint(im, "%V", nipmask); av[1] = ia; av[2] = im; ipifcadd(ifc, av, 3, 0, nil); if(gwip != 0) { hnputl(ngwip, gwip); n = sprint(ia, "add 0.0.0.0 0.0.0.0 %V", ngwip); routewrite(ifc->conv->p->f, nil, ia, n); } return nil; }
/* * call up the connection server and get a translation */ static int nettrans(char *addr, char *naddr, int na, char *file, int nf) { int i, fd; char buf[Maxpath]; char netdir[NETPATHLEN]; char *p, *p2; long n; /* * parse, get network directory */ p = strchr(addr, '!'); if(p == 0){ kwerrstr("bad dial string: %s", addr); return -1; } if(*addr != '/'){ strcpy(netdir, "/net"); } else { for(p2 = p; *p2 != '/'; p2--) ; i = p2 - addr; if(i == 0 || i >= sizeof(netdir)){ kwerrstr("bad dial string: %s", addr); return -1; } strncpy(netdir, addr, i); netdir[i] = 0; addr = p2 + 1; } /* * ask the connection server */ sprint(buf, "%s/cs", netdir); fd = kopen(buf, ORDWR); if(fd < 0) return identtrans(netdir, addr, naddr, na, file, nf); if(kwrite(fd, addr, strlen(addr)) < 0){ kclose(fd); return -1; } kseek(fd, 0, 0); n = kread(fd, buf, sizeof(buf)-1); kclose(fd); if(n <= 0) return -1; buf[n] = 0; /* * parse the reply */ p = strchr(buf, ' '); if(p == 0) return -1; *p++ = 0; strncpy(naddr, p, na); naddr[na-1] = 0; strncpy(file, buf, nf); file[nf-1] = 0; return 0; }
int main () { // INIT FS HERE init_fs(); int retval, i; int fd; int index_node_number; /* Some arbitrary data for our files */ memset (data1, '1', sizeof (data1)); memset (data2, '2', sizeof (data2)); memset (data3, '3', sizeof (data3)); #ifdef TEST1 kmkdir("/home"); kcreat("/home/file"); /* ****TEST 1: MAXIMUM file creation**** */ /* Assumes the pre-existence of a root directory file "/" that is neither created nor deleted in this test sequence */ /* Generate MAXIMUM regular files */ for (i = 0; i < MAX_FILES + 1; i++) { // go beyond the limit sprintf (pathname, "/file%d", i); retval = kcreat (pathname); if (retval < 0) { fprintf (stderr, "kcreate: File creation error! status: %d\n", retval); if (i != MAX_FILES) exit (1); } memset (pathname, 0, 80); } /* Delete all the files created */ for (i = 0; i < MAX_FILES; i++) { sprintf (pathname, "/file%d", i); retval = kunlink (pathname); if (retval < 0) { fprintf (stderr, "kunlink: File deletion error! status: %d\n", retval); exit (1); } memset (pathname, 0, 80); } #endif // TEST1 #ifdef TEST2 /* ****TEST 2: LARGEST file size**** */ /* Generate one LARGEST file */ retval = kcreat ("/bigfile"); if (retval < 0) { fprintf (stderr, "kcreat: File creation error! status: %d\n", retval); exit (1); } printf("kcreat succesful\n"); retval = kopen ("/bigfile"); /* Open file to write to it */ if (retval < 0) { fprintf (stderr, "kopen: File open error! status: %d\n", retval); exit (1); } printf("kopen succesful\n"); fd = retval; /* Assign valid fd */ /* Try writing to all direct data blocks */ retval = kwrite (fd, data1, sizeof(data1)); if (retval < 0) { fprintf (stderr, "kwrite: File write STAGE1 error! status: %d\n", retval); exit (1); } printf("kwrite direct succesful\n"); #ifdef TEST_SINGLE_INDIRECT /* Try writing to all single-indirect data blocks */ retval = kwrite (fd, data2, sizeof(data2)); if (retval < 0) { fprintf (stderr, "kwrite: File write STAGE2 error! status: %d\n", retval); exit (1); } printf("kwrite 1 indirect succesful\n"); #ifdef TEST_DOUBLE_INDIRECT /* Try writing to all double-indirect data blocks */ retval = kwrite (fd, data3, sizeof(data3)); printf("kwrite 2 actually writes = %d, suppose to write = %ld\n", retval, sizeof(data3)); if (retval < 0) { fprintf (stderr, "kwrite: File write STAGE3 error! status: %d\n", retval); exit (1); } printf("PASSED TEST2\n"); #endif // TEST_DOUBLE_INDIRECT #endif // TEST_SINGLE_INDIRECT #endif // TEST2 #ifdef TEST3 /* ****TEST 3: Seek and Read file test**** */ retval = klseek (fd, 0); /* Go back to the beginning of your file */ if (retval < 0) { fprintf (stderr, "klseek: File seek error! status: %d\n", retval); exit (1); } /* Try reading from all direct data blocks */ retval = kread (fd, addr, sizeof(data1)); if (retval < 0) { fprintf (stderr, "kread: File read STAGE1 error! status: %d\n", retval); exit (1); } /* Should be all 1s here... */ printf ("Data at addr: %s\n", addr); printf("PASSED TEST3-Direct Block read\n"); #ifdef TEST_SINGLE_INDIRECT /* Try reading from all single-indirect data blocks */ retval = kread (fd, addr, sizeof(data2)); if (retval < 0) { fprintf (stderr, "kread: File read STAGE2 error! status: %d\n", retval); exit (1); } /* Should be all 2s here... */ printf ("Data at addr: %s\n", addr); printf("PASSED TEST3-1 Redirect Block read\n"); #ifdef TEST_DOUBLE_INDIRECT /* Try reading from all double-indirect data blocks */ retval = kread (fd, addr, sizeof(data3)); if (retval < 0) { fprintf (stderr, "kread: File read STAGE3 error! status: %d\n", retval); exit (1); } /* Should be all 3s here... */ printf ("Data at addr: %s\n", addr); printf("PASSED TEST3-2 Redirect Block read\n"); #endif // TEST_DOUBLE_INDIRECT #endif // TEST_SINGLE_INDIRECT /* Close the bigfile */ retval = kclose (fd); if (retval < 0) { fprintf (stderr, "kclose: File close error! status: %d\n", retval); exit (1); } /* Remove the biggest file */ retval = kunlink ("/bigfile"); if (retval < 0) { fprintf (stderr, "kunlink: /bigfile file deletion error! status: %d\n", retval); exit (1); } #endif // TEST3 #ifdef TEST4 /* ****TEST 4: Make directory and read directory entries**** */ retval = kmkdir ("/dir1"); if (retval < 0) { fprintf (stderr, "kmkdir: Directory 1 creation error! status: %d\n", retval); exit (1); } retval = kmkdir ("/dir1/dir2"); if (retval < 0) { fprintf (stderr, "kmkdir: Directory 2 creation error! status: %d\n", retval); exit (1); } retval = kmkdir ("/dir1/dir3"); if (retval < 0) { fprintf (stderr, "kmkdir: Directory 3 creation error! status: %d\n", retval); exit (1); } retval = kopen ("/dir1"); /* Open directory file to read its entries */ if (retval < 0) { fprintf (stderr, "kopen: Directory open error! status: %d\n", retval); exit (1); } fd = retval; /* Assign valid fd */ memset (addr, 0, sizeof(addr)); /* Clear scratchpad memory */ while ((retval = kreaddir (fd, addr))) { /* 0 indicates end-of-file */ if (retval < 0) { fprintf (stderr, "kreaddir: Directory read error! status: %d\n", retval); exit (1); } /* printf("user\n"); int zz = 0; for (zz; zz < 16; zz++) { printf("%d ", *((unsigned char *)addr + zz)); } printf("\n"); */ index_node_number = atoi(&addr[14]); printf ("Contents at addr: [%s,%d]\n", addr, index_node_number); } #endif // TEST4 #ifdef TEST5 /* ****TEST 5: 2 process test**** */ if((retval = fork())) { if(retval == -1) { fprintf(stderr, "Failed to fork\n"); exit(1); } /* Generate 300 regular files */ for (i = 0; i < 300; i++) { sprintf (pathname, "/file_p_%d", i); retval = kcreat (pathname); if (retval < 0) { fprintf (stderr, "(Parent) kcreate: File creation error! status: %d\n", retval); exit(1); } memset (pathname, 0, 80); } } else { /* Generate 300 regular files */ for (i = 0; i < 300; i++) { sprintf (pathname, "/file_c_%d", i); retval = kcreat (pathname); if (retval < 0) { fprintf (stderr, "(Child) kcreate: File creation error! status: %d\n", retval); exit(1); } memset (pathname, 0, 80); } } #endif // TEST5 fprintf(stdout, "Congratulations, you have passed all tests!!\n"); return 0; }