/* fread - read file contents * * fread ( fd buf nbytes -- nread ) */ static void pfread(FICL_VM *pVM) { int fd, len; char *buf; #if FICL_ROBUST > 1 vmCheckStack(pVM, 3, 1); #endif len = stackPopINT(pVM->pStack); /* get number of bytes to read */ buf = stackPopPtr(pVM->pStack); /* get buffer */ fd = stackPopINT(pVM->pStack); /* get fd */ if (len > 0 && buf && fd != -1) stackPushINT(pVM->pStack, read(fd, buf, len)); else stackPushINT(pVM->pStack, -1); return; }
static void ficlWriteFile(FICL_VM *pVM) /* ( c-addr u1 fileid -- ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); int length = stackPopINT(pVM->pStack); void *address = (void *)stackPopPtr(pVM->pStack); clearerr(ff->f); fwrite(address, 1, length, ff->f); pushIor(pVM, ferror(ff->f) == 0); }
/* * outb ( port# c -- ) * Store a byte to I/O port number port# */ void ficlOutb(FICL_VM *pVM) { u_char c; u_int32_t port; port=stackPopUNS(pVM->pStack); c=(u_char)stackPopINT(pVM->pStack); outb(port,c); }
static void ficlDeleteFile(FICL_VM *pVM) /* ( c-addr u -- ior ) */ { int length = stackPopINT(pVM->pStack); void *address = (void *)stackPopPtr(pVM->pStack); char *filename = (char *)alloca(length + 1); memcpy(filename, address, length); filename[length] = 0; pushIor(pVM, !unlink(filename)); }
static void ficlWriteLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); size_t length = (size_t)stackPopINT(pVM->pStack); void *address = (void *)stackPopPtr(pVM->pStack); clearerr(ff->f); if (fwrite(address, 1, length, ff->f) == length) fwrite("\n", 1, 1, ff->f); pushIor(pVM, ferror(ff->f) == 0); }
/* * pcibios-device-count (devid -- count) * * Returns the PCI BIOS' count of how many devices matching devid are in the system. * devid is the 32-bit vendor + device. */ static void ficlPciBiosCountDevices(FICL_VM *pVM) { uint32_t devid; int i; devid = stackPopINT(pVM->pStack); i = biospci_count_device_type(devid); stackPushINT(pVM->pStack, i); }
void ficlCopyout(FICL_VM *pVM) { void* dest; vm_offset_t src; size_t len; #if FICL_ROBUST > 1 vmCheckStack(pVM, 3, 0); #endif len = stackPopINT(pVM->pStack); dest = stackPopPtr(pVM->pStack); src = stackPopINT(pVM->pStack); #ifndef TESTMAIN archsw.arch_copyout(src, dest, len); #endif return; }
/* fload - interpret file contents * * fload ( fd -- ) */ static void pfload(FICL_VM *pVM) { int fd; #if FICL_ROBUST > 1 vmCheckStack(pVM, 1, 0); #endif fd = stackPopINT(pVM->pStack); /* get fd */ if (fd != -1) ficlExecFD(pVM, fd); return; }
/* fclose - close a file who's fd is on stack. * * fclose ( fd -- ) */ static void pfclose(FICL_VM *pVM) { int fd; #if FICL_ROBUST > 1 vmCheckStack(pVM, 1, 0); #endif fd = stackPopINT(pVM->pStack); /* get fd */ if (fd != -1) close(fd); return; }
static void ficlReadFile(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); int length = stackPopINT(pVM->pStack); void *address = (void *)stackPopPtr(pVM->pStack); int result; clearerr(ff->f); result = fread(address, 1, length, ff->f); stackPushINT(pVM->pStack, result); pushIor(pVM, ferror(ff->f) == 0); }
static void ficlRenameFile(FICL_VM *pVM) /* ( c-addr1 u1 c-addr2 u2 -- ior ) */ { int length; void *address; char *from; char *to; length = stackPopINT(pVM->pStack); address = (void *)stackPopPtr(pVM->pStack); to = (char *)alloca(length + 1); memcpy(to, address, length); to[length] = 0; length = stackPopINT(pVM->pStack); address = (void *)stackPopPtr(pVM->pStack); from = (char *)alloca(length + 1); memcpy(from, address, length); from[length] = 0; pushIor(pVM, !rename(from, to)); }
/* fkey - get a character from a file * * fkey ( file -- char ) */ static void fkey(FICL_VM *pVM) { int i, fd; char ch; #if FICL_ROBUST > 1 vmCheckStack(pVM, 1, 1); #endif fd = stackPopINT(pVM->pStack); i = read(fd, &ch, 1); stackPushINT(pVM->pStack, i > 0 ? ch : -1); return; }
void ficlFindfile(FICL_VM *pVM) { #ifndef TESTMAIN char *name; #endif char *type, *namep, *typep; struct preloaded_file* fp; int names, types; #if FICL_ROBUST > 1 vmCheckStack(pVM, 4, 1); #endif types = stackPopINT(pVM->pStack); typep = (char*) stackPopPtr(pVM->pStack); names = stackPopINT(pVM->pStack); namep = (char*) stackPopPtr(pVM->pStack); #ifndef TESTMAIN name = (char*) ficlMalloc(names+1); if (!name) vmThrowErr(pVM, "Error: out of memory"); strncpy(name, namep, names); name[names] = '\0'; type = (char*) ficlMalloc(types+1); if (!type) vmThrowErr(pVM, "Error: out of memory"); strncpy(type, typep, types); type[types] = '\0'; fp = file_findfile(name, type); #else fp = NULL; #endif stackPushPtr(pVM->pStack, fp); return; }
void ficlSetenvq(FICL_VM *pVM) { #ifndef TESTMAIN char *name, *value; #endif char *namep, *valuep; int names, values, overwrite; #if FICL_ROBUST > 1 vmCheckStack(pVM, 5, 0); #endif overwrite = stackPopINT(pVM->pStack); names = stackPopINT(pVM->pStack); namep = (char*) stackPopPtr(pVM->pStack); values = stackPopINT(pVM->pStack); valuep = (char*) stackPopPtr(pVM->pStack); #ifndef TESTMAIN name = (char*) ficlMalloc(names+1); if (!name) vmThrowErr(pVM, "Error: out of memory"); strncpy(name, namep, names); name[names] = '\0'; value = (char*) ficlMalloc(values+1); if (!value) vmThrowErr(pVM, "Error: out of memory"); strncpy(value, valuep, values); value[values] = '\0'; setenv(name, value, overwrite); ficlFree(name); ficlFree(value); #endif return; }
void ficlUuidFromString(FICL_VM *pVM) { #ifndef TESTMAIN char *uuid; uint32_t status; #endif char *uuidp; int uuids; uuid_t *u; #if FICL_ROBUST > 1 vmCheckStack(pVM, 2, 0); #endif uuids = stackPopINT(pVM->pStack); uuidp = (char *) stackPopPtr(pVM->pStack); #ifndef TESTMAIN uuid = (char *)ficlMalloc(uuids + 1); if (!uuid) vmThrowErr(pVM, "Error: out of memory"); strncpy(uuid, uuidp, uuids); uuid[uuids] = '\0'; u = (uuid_t *)ficlMalloc(sizeof (*u)); uuid_from_string(uuid, u, &status); ficlFree(uuid); if (status != uuid_s_ok) { ficlFree(u); u = NULL; } #else u = NULL; #endif stackPushPtr(pVM->pStack, u); return; }
static void ficlReadLine(FICL_VM *pVM) /* ( c-addr u1 fileid -- u2 flag ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); int length = stackPopINT(pVM->pStack); char *address = (char *)stackPopPtr(pVM->pStack); int error; int flag; if (feof(ff->f)) { stackPushINT(pVM->pStack, -1); stackPushINT(pVM->pStack, 0); stackPushINT(pVM->pStack, 0); return; } clearerr(ff->f); *address = 0; fgets(address, length, ff->f); error = ferror(ff->f); if (error != 0) { stackPushINT(pVM->pStack, -1); stackPushINT(pVM->pStack, 0); stackPushINT(pVM->pStack, error); return; } length = strlen(address); flag = (length > 0); if (length && ((address[length - 1] == '\r') || (address[length - 1] == '\n'))) length--; stackPushINT(pVM->pStack, length); stackPushINT(pVM->pStack, flag); stackPushINT(pVM->pStack, 0); /* ior */ }
/* isdir? - Return whether an fd corresponds to a directory. * * isdir? ( fd -- bool ) */ static void isdirQuestion(FICL_VM *pVM) { struct stat sb; FICL_INT flag; int fd; #if FICL_ROBUST > 1 vmCheckStack(pVM, 1, 1); #endif fd = stackPopINT(pVM->pStack); flag = FICL_FALSE; do { if (fd < 0) break; if (fstat(fd, &sb) < 0) break; if (!S_ISDIR(sb.st_mode)) break; flag = FICL_TRUE; } while (0); stackPushINT(pVM->pStack, flag); }
/* * Shim for taking commands from BF and passing them out to 'standard' * argv/argc command functions. */ static void bf_command(FICL_VM *vm) { char *name, *line, *tail, *cp; size_t len; struct bootblk_command **cmdp; bootblk_cmd_t *cmd; int nstrings, i; int argc, result; char **argv; /* Get the name of the current word */ name = vm->runningWord->name; /* Find our command structure */ cmd = NULL; SET_FOREACH(cmdp, Xcommand_set) { if (((*cmdp)->c_name != NULL) && !strcmp(name, (*cmdp)->c_name)) cmd = (*cmdp)->c_fn; } if (cmd == NULL) panic("callout for unknown command '%s'", name); /* Check whether we have been compiled or are being interpreted */ if (stackPopINT(vm->pStack)) { /* * Get parameters from stack, in the format: * an un ... a2 u2 a1 u1 n -- * Where n is the number of strings, a/u are pairs of * address/size for strings, and they will be concatenated * in LIFO order. */ nstrings = stackPopINT(vm->pStack); for (i = 0, len = 0; i < nstrings; i++) len += stackFetch(vm->pStack, i * 2).i + 1; line = malloc(strlen(name) + len + 1); strcpy(line, name); if (nstrings) for (i = 0; i < nstrings; i++) { len = stackPopINT(vm->pStack); cp = stackPopPtr(vm->pStack); strcat(line, " "); strncat(line, cp, len); } } else { /* Get remainder of invocation */ tail = vmGetInBuf(vm); for (cp = tail, len = 0; cp != vm->tib.end && *cp != 0 && *cp != '\n'; cp++, len++) ; line = malloc(strlen(name) + len + 2); strcpy(line, name); if (len > 0) { strcat(line, " "); strncat(line, tail, len); vmUpdateTib(vm, tail + len); } } DEBUG("cmd '%s'", line); command_errmsg = command_errbuf; command_errbuf[0] = 0; if (!parse(&argc, &argv, line)) { result = (cmd)(argc, argv); free(argv); } else { result=BF_PARSE; } free(line); /* This is going to be thrown!!! */ stackPushINT(vm->pStack,result); }
/* freaddir - read directory contents * * freaddir ( fd -- ptr len TRUE | FALSE ) */ static void pfreaddir(FICL_VM *pVM) { #ifdef TESTMAIN static struct dirent dirent; struct stat sb; char *buf; off_t off, ptr; u_int blksz; int bufsz; #endif struct dirent *d; int fd; #if FICL_ROBUST > 1 vmCheckStack(pVM, 1, 3); #endif fd = stackPopINT(pVM->pStack); #if TESTMAIN /* * The readdirfd() function is specific to the loader environment. * We do the best we can to make freaddir work, but it's not at * all guaranteed. */ d = NULL; buf = NULL; do { if (fd == -1) break; if (fstat(fd, &sb) == -1) break; blksz = (sb.st_blksize) ? sb.st_blksize : getpagesize(); if ((blksz & (blksz - 1)) != 0) break; buf = malloc(blksz); if (buf == NULL) break; off = lseek(fd, 0LL, SEEK_CUR); if (off == -1) break; ptr = off; if (lseek(fd, 0, SEEK_SET) == -1) break; bufsz = getdents(fd, buf, blksz); while (bufsz > 0 && bufsz <= ptr) { ptr -= bufsz; bufsz = getdents(fd, buf, blksz); } if (bufsz <= 0) break; d = (void *)(buf + ptr); dirent = *d; off += d->d_reclen; d = (lseek(fd, off, SEEK_SET) != off) ? NULL : &dirent; } while (0); if (buf != NULL) free(buf); #else d = readdirfd(fd); #endif if (d != NULL) { stackPushPtr(pVM->pStack, d->d_name); stackPushINT(pVM->pStack, strlen(d->d_name)); stackPushINT(pVM->pStack, FICL_TRUE); } else { stackPushINT(pVM->pStack, FICL_FALSE); } }
static void fTempBase(FICL_VM *pVM) { int base = stackPopINT(pVM->pStack); tempBase(pVM, base); return; }
/* * pcibios-find-devclass (class index -- locator) * * Finds the index'th instance of class in the pci tree. * must be an exact match. * class is the class to search for. * index 0..N (set to 0, increment until error) * * Locator is bus << 8 | device << 3 | fuction (or -1 on error) */ static void ficlPciBiosFindDevclass(FICL_VM *pVM) { uint32_t index, class, locator; index = stackPopINT(pVM->pStack); class = stackPopINT(pVM->pStack); if (biospci_find_devclass(class, index, &locator)) locator = 0xffffffff; stackPushINT(pVM->pStack, locator); } /* * pcibios-find-device(devid index -- locator) * * Finds the index'th instance of devid in the pci tree. * must be an exact match. * class is the class to search for. * index 0..N (set to 0, increment until error)