Index: head/stand/ficl/fileaccess.c =================================================================== --- head/stand/ficl/fileaccess.c (revision 358812) +++ head/stand/ficl/fileaccess.c (revision 358813) @@ -1,432 +1,432 @@ /* $FreeBSD$ */ #include #include #include #include #include #include #include "ficl.h" #if FICL_WANT_FILE /* ** ** fileaccess.c ** ** Implements all of the File Access word set that can be implemented in portable C. ** */ static void pushIor(FICL_VM *pVM, int success) { int ior; if (success) ior = 0; else ior = errno; stackPushINT(pVM->pStack, ior); } static void ficlFopen(FICL_VM *pVM, char *writeMode) /* ( c-addr u fam -- fileid ior ) */ { int fam = stackPopINT(pVM->pStack); int length = stackPopINT(pVM->pStack); void *address = (void *)stackPopPtr(pVM->pStack); char mode[4]; FILE *f; char *filename = (char *)alloca(length + 1); memcpy(filename, address, length); filename[length] = 0; *mode = 0; switch (FICL_FAM_OPEN_MODE(fam)) { case 0: stackPushPtr(pVM->pStack, NULL); stackPushINT(pVM->pStack, EINVAL); return; case FICL_FAM_READ: strcat(mode, "r"); break; case FICL_FAM_WRITE: strcat(mode, writeMode); break; case FICL_FAM_READ | FICL_FAM_WRITE: strcat(mode, writeMode); strcat(mode, "+"); break; } strcat(mode, (fam & FICL_FAM_BINARY) ? "b" : "t"); f = fopen(filename, mode); if (f == NULL) stackPushPtr(pVM->pStack, NULL); else #ifdef LOADER_VERIEXEC if (*mode == 'r' && - verify_file(fileno(f), filename, 0, VE_GUESS) < 0) { + verify_file(fileno(f), filename, 0, VE_GUESS, __func__) < 0) { fclose(f); stackPushPtr(pVM->pStack, NULL); } else #endif { ficlFILE *ff = (ficlFILE *)malloc(sizeof(ficlFILE)); strcpy(ff->filename, filename); ff->f = f; stackPushPtr(pVM->pStack, ff); fseek(f, 0, SEEK_SET); } pushIor(pVM, f != NULL); } static void ficlOpenFile(FICL_VM *pVM) /* ( c-addr u fam -- fileid ior ) */ { ficlFopen(pVM, "a"); } static void ficlCreateFile(FICL_VM *pVM) /* ( c-addr u fam -- fileid ior ) */ { ficlFopen(pVM, "w"); } static int closeFiclFILE(ficlFILE *ff) /* ( fileid -- ior ) */ { FILE *f = ff->f; free(ff); return !fclose(f); } static void ficlCloseFile(FICL_VM *pVM) /* ( fileid -- ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); pushIor(pVM, closeFiclFILE(ff)); } 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 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)); } static void ficlFileStatus(FICL_VM *pVM) /* ( c-addr u -- x ior ) */ { struct stat statbuf; int length = stackPopINT(pVM->pStack); void *address = (void *)stackPopPtr(pVM->pStack); char *filename = (char *)alloca(length + 1); memcpy(filename, address, length); filename[length] = 0; if (stat(filename, &statbuf) == 0) { /* ** the "x" left on the stack is implementation-defined. ** I push the file's access mode (readable, writeable, is directory, etc) ** as defined by ANSI C. */ stackPushINT(pVM->pStack, statbuf.st_mode); stackPushINT(pVM->pStack, 0); } else { stackPushINT(pVM->pStack, -1); stackPushINT(pVM->pStack, ENOENT); } } static void ficlFilePosition(FICL_VM *pVM) /* ( fileid -- ud ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); long ud = ftell(ff->f); stackPushINT(pVM->pStack, ud); pushIor(pVM, ud != -1); } static long fileSize(FILE *f) { struct stat statbuf; statbuf.st_size = -1; if (fstat(fileno(f), &statbuf) != 0) return -1; return statbuf.st_size; } static void ficlFileSize(FICL_VM *pVM) /* ( fileid -- ud ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); long ud = fileSize(ff->f); stackPushINT(pVM->pStack, ud); pushIor(pVM, ud != -1); } #define nLINEBUF 256 static void ficlIncludeFile(FICL_VM *pVM) /* ( i*x fileid -- j*x ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); CELL id = pVM->sourceID; int result = VM_OUTOFTEXT; long currentPosition, totalSize; long size; pVM->sourceID.p = (void *)ff; currentPosition = ftell(ff->f); totalSize = fileSize(ff->f); size = totalSize - currentPosition; if ((totalSize != -1) && (currentPosition != -1) && (size > 0)) { char *buffer = (char *)malloc(size); long got = fread(buffer, 1, size, ff->f); if (got == size) result = ficlExecC(pVM, buffer, size); } #if 0 ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); CELL id = pVM->sourceID; char cp[nLINEBUF]; int nLine = 0; int keepGoing; int result; pVM->sourceID.p = (void *)ff; /* feed each line to ficlExec */ keepGoing = TRUE; while (keepGoing && fgets(cp, nLINEBUF, ff->f)) { int len = strlen(cp) - 1; nLine++; if (len <= 0) continue; if (cp[len] == '\n') cp[len] = '\0'; result = ficlExec(pVM, cp); switch (result) { case VM_OUTOFTEXT: case VM_USEREXIT: break; default: pVM->sourceID = id; keepGoing = FALSE; break; } } #endif /* 0 */ /* ** Pass an empty line with SOURCE-ID == -1 to flush ** any pending REFILLs (as required by FILE wordset) */ pVM->sourceID.i = -1; ficlExec(pVM, ""); pVM->sourceID = id; closeFiclFILE(ff); } 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 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 */ } 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); } 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); } static void ficlRepositionFile(FICL_VM *pVM) /* ( ud fileid -- ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); size_t ud = (size_t)stackPopINT(pVM->pStack); pushIor(pVM, fseek(ff->f, ud, SEEK_SET) == 0); } static void ficlFlushFile(FICL_VM *pVM) /* ( fileid -- ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); pushIor(pVM, fflush(ff->f) == 0); } #if FICL_HAVE_FTRUNCATE static void ficlResizeFile(FICL_VM *pVM) /* ( ud fileid -- ior ) */ { ficlFILE *ff = (ficlFILE *)stackPopPtr(pVM->pStack); size_t ud = (size_t)stackPopINT(pVM->pStack); pushIor(pVM, ftruncate(fileno(ff->f), ud) == 0); } #endif /* FICL_HAVE_FTRUNCATE */ #endif /* FICL_WANT_FILE */ void ficlCompileFile(FICL_SYSTEM *pSys) { #if FICL_WANT_FILE FICL_DICT *dp = pSys->dp; assert(dp); dictAppendWord(dp, "create-file", ficlCreateFile, FW_DEFAULT); dictAppendWord(dp, "open-file", ficlOpenFile, FW_DEFAULT); dictAppendWord(dp, "close-file", ficlCloseFile, FW_DEFAULT); dictAppendWord(dp, "include-file", ficlIncludeFile, FW_DEFAULT); dictAppendWord(dp, "read-file", ficlReadFile, FW_DEFAULT); dictAppendWord(dp, "read-line", ficlReadLine, FW_DEFAULT); dictAppendWord(dp, "write-file", ficlWriteFile, FW_DEFAULT); dictAppendWord(dp, "write-line", ficlWriteLine, FW_DEFAULT); dictAppendWord(dp, "file-position", ficlFilePosition, FW_DEFAULT); dictAppendWord(dp, "file-size", ficlFileSize, FW_DEFAULT); dictAppendWord(dp, "reposition-file", ficlRepositionFile, FW_DEFAULT); dictAppendWord(dp, "file-status", ficlFileStatus, FW_DEFAULT); dictAppendWord(dp, "flush-file", ficlFlushFile, FW_DEFAULT); dictAppendWord(dp, "delete-file", ficlDeleteFile, FW_DEFAULT); dictAppendWord(dp, "rename-file", ficlRenameFile, FW_DEFAULT); #ifdef FICL_HAVE_FTRUNCATE dictAppendWord(dp, "resize-file", ficlResizeFile, FW_DEFAULT); ficlSetEnv(pSys, "file", FICL_TRUE); ficlSetEnv(pSys, "file-ext", FICL_TRUE); #endif /* FICL_HAVE_FTRUNCATE */ #else (void)pSys; #endif /* FICL_WANT_FILE */ } Index: head/stand/i386/loader/chain.c =================================================================== --- head/stand/i386/loader/chain.c (revision 358812) +++ head/stand/i386/loader/chain.c (revision 358813) @@ -1,169 +1,169 @@ /*- * Copyright 2015 Toomas Soome * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Chain loader to load BIOS boot block either from MBR or PBR. * * Note the boot block location 0000:7c000 conflicts with loader, so we need to * read in to temporary space and relocate on exec, when btx is stopped. */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include "bootstrap.h" #include "libi386/libi386.h" #include "btxv86.h" #ifdef LOADER_VERIEXEC_VECTX #define VECTX_HANDLE(x) vctx #else #define VECTX_HANDLE(x) x #endif /* * The MBR/VBR is located in first sector of disk/partition. * Read 512B to temporary location and set up relocation. Then * exec relocator. */ #define SECTOR_SIZE (512) COMMAND_SET(chain, "chain", "chain load boot block from device", command_chain); static int command_chain(int argc, char *argv[]) { int fd, len, size = SECTOR_SIZE; struct stat st; vm_offset_t mem = 0x100000; struct i386_devdesc *rootdev; #ifdef LOADER_VERIEXEC_VECTX struct vectx *vctx; int verror; #endif if (argc == 1) { command_errmsg = "no device or file name specified"; return (CMD_ERROR); } if (argc != 2) { command_errmsg = "invalid trailing arguments"; return (CMD_ERROR); } fd = open(argv[1], O_RDONLY); if (fd == -1) { command_errmsg = "open failed"; return (CMD_ERROR); } #ifdef LOADER_VERIEXEC_VECTX vctx = vectx_open(fd, argv[1], 0L, NULL, &verror, __func__); if (verror) { sprintf(command_errbuf, "can't verify: %s", argv[1]); close(fd); free(vctx); return (CMD_ERROR); } #else #ifdef LOADER_VERIEXEC - if (verify_file(fd, argv[1], 0, VE_MUST) < 0) { + if (verify_file(fd, argv[1], 0, VE_MUST, __func__) < 0) { sprintf(command_errbuf, "can't verify: %s", argv[1]); close(fd); return (CMD_ERROR); } #endif #endif len = strlen(argv[1]); if (argv[1][len-1] != ':') { if (fstat(fd, &st) == -1) { command_errmsg = "stat failed"; close(fd); return (CMD_ERROR); } size = st.st_size; } else if (strncmp(argv[1], "disk", 4) != 0) { command_errmsg = "can only use disk device"; close(fd); return (CMD_ERROR); } i386_getdev((void **)(&rootdev), argv[1], NULL); if (rootdev == NULL) { command_errmsg = "can't determine root device"; close(fd); return (CMD_ERROR); } if (archsw.arch_readin(VECTX_HANDLE(fd), mem, size) != size) { command_errmsg = "failed to read disk"; close(fd); return (CMD_ERROR); } close(fd); #ifdef LOADER_VERIEXEC_VECTX verror = vectx_close(vctx, VE_MUST, __func__); if (verror) { free(vctx); return (CMD_ERROR); } #endif if (argv[1][len-1] == ':' && *((uint16_t *)PTOV(mem + DOSMAGICOFFSET)) != DOSMAGIC) { command_errmsg = "wrong magic"; return (CMD_ERROR); } relocater_data[0].src = mem; relocater_data[0].dest = 0x7C00; relocater_data[0].size = size; relocator_edx = bd_unit2bios(rootdev); relocator_esi = relocater_size; relocator_ds = 0; relocator_es = 0; relocator_fs = 0; relocator_gs = 0; relocator_ss = 0; relocator_cs = 0; relocator_sp = 0x7C00; relocator_ip = 0x7C00; relocator_a20_enabled = 0; i386_copyin(relocater, 0x600, relocater_size); dev_cleanup(); __exec((void *)0x600); panic("exec returned"); return (CMD_ERROR); /* not reached */ }