QemuLog.txt
Screenshots/
-Tools/*/src/obj/
-Tools/*/src/Makefile.BuildNum
-Tools/DiskTool/DiskTool
+Tools/*/obj/
+Tools/*/Makefile.BuildNum
+Tools/disktool
+Tools/nettest
+Tools/img2sif
Term->CurColour &= 0xFFFF8000;
Term->CurColour |= caVT100Colours[ colour_idx ];
}
+ // Foreground Colour - bright
+ else if(90 <= args[argc] && args[argc] <= 97 ) {
+ colour_idx = args[argc]-90 + 8;
+ Term->CurColour &= 0x8000FFFF;
+ Term->CurColour |= (Uint32)caVT100Colours[ colour_idx ] << 16;
+ }
+ // Background Colour - bright
+ else if(100 <= args[argc] && args[argc] <= 107 ) {
+ colour_idx = args[argc]-100 + 8;
+ Term->CurColour &= 0xFFFF8000;
+ Term->CurColour |= (Uint32)caVT100Colours[ colour_idx ];
+ }
else {
Log_Warning("VTerm", "Unknown font flag %i", args[argc]);
}
*/
// --- Strings ---
-/**
- * \name Strings
- * \{
- */
-extern int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args);
-extern int snprintf(char *__s, size_t __n, const char *__format, ...);
-extern int sprintf(char *__s, const char *__format, ...);
-extern size_t strlen(const char *Str);
-extern char *strcpy(char *__dest, const char *__src);
-extern char *strncpy(char *__dest, const char *__src, size_t max);
-extern char *strcat(char *__dest, const char *__src);
-extern char *strncat(char *__dest, const char *__src, size_t n);
-extern int strcmp(const char *__str1, const char *__str2);
-extern int strncmp(const char *Str1, const char *Str2, size_t num);
-extern int strucmp(const char *Str1, const char *Str2);
-// strdup macro is defined in heap.h
-extern char *_strdup(const char *File, int Line, const char *Str);
-extern char **str_split(const char *__str, char __ch);
-extern char *strchr(const char *__s, int __c);
-extern char *strrchr(const char *__s, int __c);
-extern int strpos(const char *Str, char Ch);
-extern int strpos8(const char *str, Uint32 search);
-extern void itoa(char *buf, Uint64 num, int base, int minLength, char pad);
-extern int atoi(const char *string);
-extern unsigned long long strtoull(const char *str, char **end, int base);
-extern unsigned long strtoul(const char *str, char **end, int base);
-extern signed long long strtoll(const char *str, char **end, int base);
-extern signed long strtol(const char *str, char **end, int base);
-extern int ParseInt(const char *string, int *Val);
-extern int ReadUTF8(const Uint8 *str, Uint32 *Val);
-extern int WriteUTF8(Uint8 *str, Uint32 Val);
-extern int ModUtil_SetIdent(char *Dest, const char *Value);
-extern int ModUtil_LookupString(const char **Array, const char *Needle);
-
-extern Uint8 ByteSum(const void *Ptr, int Size);
-extern int Hex(char *Dest, size_t Size, const Uint8 *SourceData);
-extern int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString);
-/**
- * \}
- */
+#include <acess_string.h>
#include <ctype.h>
--- /dev/null
+/*
+ * Acess2 Kernel
+ * - By John Hodge (thePowersGang)
+ *
+ * acess_string.h
+ * - Kernel-land string.h
+ */
+#ifndef _ACESS_STRING_H
+#define _ACESS_STRING_H
+#include <stdarg.h>
+
+/**
+ * \name Strings
+ * \{
+ */
+// - stdio.h in userland
+extern int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args);
+extern int snprintf(char *__s, size_t __n, const char *__format, ...);
+extern int sprintf(char *__s, const char *__format, ...);
+extern size_t strlen(const char *Str);
+extern char *strcpy(char *__dest, const char *__src);
+extern char *strncpy(char *__dest, const char *__src, size_t max);
+extern char *strcat(char *__dest, const char *__src);
+extern char *strncat(char *__dest, const char *__src, size_t n);
+extern int strcmp(const char *__str1, const char *__str2);
+extern int strncmp(const char *Str1, const char *Str2, size_t num);
+// strdup macro is defined in heap.h
+extern char *_strdup(const char *File, int Line, const char *Str);
+extern char **str_split(const char *__str, char __ch);
+extern char *strchr(const char *__s, int __c);
+extern char *strrchr(const char *__s, int __c);
+extern void itoa(char *buf, Uint64 num, int base, int minLength, char pad);
+extern int atoi(const char *string);
+extern unsigned long long strtoull(const char *str, char **end, int base);
+extern unsigned long strtoul(const char *str, char **end, int base);
+extern signed long long strtoll(const char *str, char **end, int base);
+extern signed long strtol(const char *str, char **end, int base);
+
+extern int strucmp(const char *Str1, const char *Str2);
+extern int strpos(const char *Str, char Ch);
+extern int strpos8(const char *str, Uint32 search);
+
+extern int ParseInt(const char *string, int *Val);
+extern int ReadUTF8(const Uint8 *str, Uint32 *Val);
+extern int WriteUTF8(Uint8 *str, Uint32 Val);
+extern int ModUtil_SetIdent(char *Dest, const char *Value);
+extern int ModUtil_LookupString(const char **Array, const char *Needle);
+
+extern Uint8 ByteSum(const void *Ptr, int Size);
+extern int Hex(char *Dest, size_t Size, const Uint8 *SourceData);
+extern int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString);
+/**
+ * \}
+ */
+#endif
#define TCP_MAX_PACKET_SIZE 1024
#define TCP_WINDOW_SIZE 0x2000
-#define TCP_RECIEVE_BUFFER_SIZE 0x4000
+#define TCP_RECIEVE_BUFFER_SIZE 0x8000
+#define TCP_DACK_THRESHOLD 4096
+#define TCP_DACK_TIMEOUT 500
// === PROTOTYPES ===
void TCP_Initialise(void);
void TCP_INT_HandleConnectionPacket(tTCPConnection *Connection, tTCPHeader *Header, int Length);
int TCP_INT_AppendRecieved(tTCPConnection *Connection, const void *Data, size_t Length);
void TCP_INT_UpdateRecievedFromFuture(tTCPConnection *Connection);
+void TCP_INT_SendACK(tTCPConnection *Connection);
Uint16 TCP_GetUnusedPort();
int TCP_AllocatePort(Uint16 Port);
int TCP_DeallocatePort(Uint16 Port);
// Syncronise sequence values
if(Header->Flags & TCP_FLAG_SYN) {
// TODO: What if the packet also has data?
+ if( Connection->LastACKSequence != Connection->NextSequenceRcv )
+ TCP_INT_SendACK(Connection);
Connection->NextSequenceRcv = ntohl(Header->SequenceNumber);
+ Connection->LastACKSequence = Connection->NextSequenceRcv;
}
// Ackowledge a sent packet
// Get length of data
dataLen = Length - (Header->DataOffset>>4)*4;
LOG("dataLen = %i", dataLen);
+// Log_Debug("TCP", "State %i, dataLen = %x", Connection->State, dataLen);
//
// State Machine
dataLen
);
if(rv != 0) {
+ Log_Notice("TCP", "TCP_INT_AppendRecieved rv %i", rv);
break;
}
LOG("0x%08x += %i", Connection->NextSequenceRcv, dataLen);
// all connections on the interface to lag.
// - Meh, no real issue, as the cache shouldn't be that large
TCP_INT_UpdateRecievedFromFuture(Connection);
-
- // ACK Packet
- // TODO: Implement delayed ACK sending
- Header->DestPort = Header->SourcePort;
- Header->SourcePort = htons(Connection->LocalPort);
- Header->AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
- Header->SequenceNumber = htonl(Connection->NextSequenceSend);
- Header->WindowSize = htons(TCP_WINDOW_SIZE);
- Header->Flags &= TCP_FLAG_SYN; // Eliminate all flags save for SYN
- Header->Flags |= TCP_FLAG_ACK; // Add ACK
- LOG("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
- TCP_SendPacket( Connection, Header, 0, NULL );
- //Connection->NextSequenceSend ++;
+
+ #if 1
+ // - Only send an ACK if we've had a burst
+ if( Connection->NextSequenceRcv > (Uint32)(TCP_DACK_THRESHOLD + Connection->LastACKSequence) )
+ {
+ TCP_INT_SendACK(Connection);
+ // - Extend TCP deferred ACK timer
+ Time_RemoveTimer(Connection->DeferredACKTimer);
+ }
+ // - Schedule the deferred ACK timer (if already scheduled, this is a NOP)
+ Time_ScheduleTimer(Connection->DeferredACKTimer, TCP_DACK_TIMEOUT);
+ #else
+ TCP_INT_SendACK(Connection);
+ #endif
}
// Check if the packet is in window
else if( WrapBetween(Connection->NextSequenceRcv, sequence_num,
{
Log_Log("TCP", "Fully out of sequence packet (0x%08x not between 0x%08x and 0x%08x), dropped",
sequence_num, Connection->NextSequenceRcv, Connection->NextSequenceRcv+TCP_WINDOW_SIZE);
- // TODO: Spec says we should send an empty ACK with the current state
+ // Spec says we should send an empty ACK with the current state
+ TCP_INT_SendACK(Connection);
}
break;
#endif
}
+void TCP_INT_SendACK(tTCPConnection *Connection)
+{
+ tTCPHeader hdr;
+ // ACK Packet
+ hdr.DataOffset = (sizeof(tTCPHeader)/4) << 4;
+ hdr.DestPort = htons(Connection->RemotePort);
+ hdr.SourcePort = htons(Connection->LocalPort);
+ hdr.AcknowlegementNumber = htonl(Connection->NextSequenceRcv);
+ hdr.SequenceNumber = htonl(Connection->NextSequenceSend);
+ hdr.WindowSize = htons(TCP_WINDOW_SIZE);
+ hdr.Flags = TCP_FLAG_ACK; // TODO: Determine if SYN is wanted too
+ hdr.Checksum = 0; // TODO: Checksum
+ hdr.UrgentPointer = 0;
+ Log_Debug("TCP", "Sending ACK for 0x%08x", Connection->NextSequenceRcv);
+ TCP_SendPacket( Connection, &hdr, 0, NULL );
+ //Connection->NextSequenceSend ++;
+ Connection->LastACKSequence = Connection->NextSequenceRcv;
+}
+
/**
* \fn Uint16 TCP_GetUnusedPort()
* \brief Gets an unused port and allocates it
conn->FuturePacketValidBytes = conn->FuturePacketData + TCP_WINDOW_SIZE;
#endif
+ conn->DeferredACKTimer = Time_AllocateTimer( (void(*)(void*)) TCP_INT_SendACK, conn);
+
SHORTLOCK(&glTCP_OutbountCons);
conn->Next = gTCP_OutbountCons;
gTCP_OutbountCons = conn;
break;
}
+ Time_RemoveTimer(conn->DeferredACKTimer);
+ Time_FreeTimer(conn->DeferredACKTimer);
free(conn);
LEAVE('-');
#include "ipstack.h"
#include <adt.h> // tRingBuffer
+#include <timers.h> // tTimer
typedef struct sTCPHeader tTCPHeader;
typedef struct sTCPListener tTCPListener;
Uint32 NextSequenceSend; //!< Next sequence value for outbound packets
Uint32 NextSequenceRcv; //!< Next expected sequence value for inbound
-
+
+ // Deferred ACK handling
+ Uint32 LastACKSequence;
+ tTimer *DeferredACKTimer;
+
#if 0
/**
* \brief Non-ACKed packets
--- /dev/null
+
+TARGET := $(shell gcc -v 2>&1 | grep Targ | awk '{print $$2}')
+
+include ../../Makefile.Version.cfg
+-include Makefile.BuildNum
+ifeq ($(BUILD_NUM),)
+BUILD_NUM = 1
+endif
+
+
+KERNEL_SRC = ../../KernelLand/Kernel/
+MODULE_SRC = ../../KernelLand/Modules/
+
+BIN = ../disktool
+# Kernel Sources (compiled with -ffreestanding)
+K_OBJ := lib.o
+K_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o
+K_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o # vfs/select.o
+K_OBJ += vfs/fs/root.o vfs/fs/devfs.o
+K_OBJ += drvutil_disk.o drv/proc.o
+# Modules
+MODULES := Storage/LVM Filesystems/FAT Filesystems/Ext2 Filesystems/NTFS
+# Local kernel soruces (same as above, but located in same directory as Makefile)
+L_OBJ = vfs_handles.o nativefs.o actions.o
+# Native Sources (compiled as usual)
+N_OBJ = main.o script.o helpers.o
+
+# Compilation Options
+CFLAGS := -Wall -std=gnu99 -g -Werror
+CPPFLAGS := -I include/ -I ../nativelib
+K_CPPFLAGS := -I $(KERNEL_SRC)include -I $(MODULE_SRC)
+LDFLAGS += -Wl,--defsym,__buildnum=$(BUILD_NUM) -g -L ../ -lnativelib
+
+BUILDINFO_OBJ := obj/$(TARGET)/buildinfo.o
+BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c)
+
+# ====================
+# == Start of Magic ==
+# ====================
+# -- Load modules ---
+$(foreach module,$(MODULES), $(eval include $(MODULE_SRC)$(module)/Makefile) $(eval M_OBJ += $(addprefix $(module)/,$(OBJ))) )
+
+# -- Apply Prefixes to object paths
+OBJ_PREFIX = obj/$(TARGET)/
+K_OBJ_PREFIX = $(OBJ_PREFIX)_Kernel/
+M_OBJ_PREFIX = $(OBJ_PREFIX)_Module/
+K_OBJ := $(addprefix $(K_OBJ_PREFIX),$(K_OBJ))
+M_OBJ := $(addprefix $(M_OBJ_PREFIX),$(M_OBJ))
+L_OBJ := $(addprefix $(OBJ_PREFIX),$(L_OBJ))
+N_OBJ := $(addprefix $(OBJ_PREFIX),$(N_OBJ))
+
+OBJ := $(N_OBJ) $(L_OBJ) $(K_OBJ) $(M_OBJ) $(BUILDINFO_OBJ)
+
+DEPFILES = $(filter %.o,$(OBJ))
+DEPFILES := $(DEPFILES:%=%.dep)
+
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+ $(RM) -f $(OBJ) $(DEPFILES) $(BIN)
+
+$(BIN): $(OBJ)
+ @echo [CC Link] -o $(BIN)
+ @$(CC) -o $(BIN) $(OBJ) $(LDFLAGS)
+ @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum
+
+$(M_OBJ): $(M_OBJ_PREFIX)%.o: $(MODULE_SRC)%.c
+ @mkdir -p $(dir $@)
+ @echo [CC Module] -o $@
+ @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
+
+$(K_OBJ): $(K_OBJ_PREFIX)%.o: $(KERNEL_SRC)%.c
+ @mkdir -p $(dir $@)
+ @echo [CC Kernel] -o $@
+ @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
+
+$(L_OBJ): $(OBJ_PREFIX)%.o: %.c
+ @mkdir -p $(dir $@)
+ @echo [CC Local] -o $@
+ @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
+
+$(N_OBJ): $(OBJ_PREFIX)%.o: %.c
+ @mkdir -p $(dir $@)
+ @echo [CC Native] -o $@
+
+# Hacky buildinfo.c file
+$(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile
+ @echo "" > $@
+ @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@
+ @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@
+ @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@
+ @echo "const char gsBuildInfo[] = \"Acess2 DiskTool v$(ACESS_VERSION)\";" >> $@
+$(BUILDINFO_OBJ): $(BUILDINFO_SRC)
+ @echo [CC] -o $@
+ @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
+
+$(OBJ): Makefile
+
+-include $(DEPFILES)
--- /dev/null
+/*
+ * Acess2 DiskTool
+ * - By John Hodge (thePowersGang)
+ *
+ * actions.c
+ * - High level actions that call the VFS
+ * # Kernel-space compiled
+ */
+#include <acess.h>
+#include <disktool_common.h>
+#include <Storage/LVM/include/lvm.h>
+
+// === IMPORTS ===
+extern int NativeFS_Install(char **Arguments);
+extern int LVM_Cleanup(void);
+
+// === PROTOTYPES ===
+void DiskTool_Initialise(void) __attribute__((constructor(101)));
+void DiskTool_Cleanup(void);
+ int DiskTool_int_TranslateOpen(const char *File, int Mode);
+ int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest);
+ int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest);
+void DiskTool_LVM_Cleanup(void *Handle);
+
+// === GLOBALS ===
+tLVM_VolType gDiskTool_VolumeType = {
+ .Name = "DiskTool",
+ .Read = DiskTool_LVM_Read,
+ .Write = DiskTool_LVM_Write,
+ .Cleanup = DiskTool_LVM_Cleanup
+};
+
+// === CODE ===
+void DiskTool_Initialise(void)
+{
+ VFS_Init();
+ NativeFS_Install(NULL);
+ VFS_MkDir("/Native");
+ VFS_Mount("/", "/Native", "nativefs", "");
+}
+
+void DiskTool_Cleanup(void)
+{
+ int vfs_rv, lvm_rv;
+ int nNochangeLoop = 0;
+ // Unmount all
+ do {
+ lvm_rv = LVM_Cleanup();
+ vfs_rv = VFS_UnmountAll();
+ Log_Debug("DiskTool", "Unmounted %i volumes", vfs_rv);
+ if( vfs_rv == 0 && lvm_rv == 0 ) {
+ nNochangeLoop ++;
+ if(nNochangeLoop == 2) {
+ Log_Error("DiskTool", "Possible handle leak");
+ break;
+ }
+ }
+ else {
+ nNochangeLoop = 0;
+ }
+ }
+ while( vfs_rv >= 0 || lvm_rv != 0 );
+}
+
+int DiskTool_RegisterLVM(const char *Identifier, const char *Path)
+{
+ int fd = DiskTool_int_TranslateOpen(Path, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
+ if(fd == -1) {
+ Log_Notice("DiskTool", "Can't open '%s' for LVM %s", Path, Identifier);
+ return -1;
+ }
+ VFS_Seek(fd, 0, SEEK_END);
+ LVM_AddVolume( &gDiskTool_VolumeType, Identifier, (void*)(tVAddr)fd, 512, VFS_Tell(fd)/512);
+ Log_Debug("DiskTool", "Registered '%s' for LVM %s", Path, Identifier);
+ return 0;
+}
+
+int DiskTool_MountImage(const char *Identifier, const char *Path)
+{
+ // Validate Identifier and make mountpoint string
+ char mountpoint[sizeof("/Mount/") + strlen(Identifier) + 1];
+ strcpy(mountpoint, "/Mount/");
+ strcat(mountpoint, Identifier);
+
+ // Translate path
+ size_t tpath_len = DiskTool_int_TranslatePath(NULL, Path);
+ char tpath[tpath_len-1];
+ DiskTool_int_TranslatePath(tpath, Path);
+
+ // Call mount
+ VFS_MkDir(mountpoint);
+ // TODO: Detect filesystem?
+ return VFS_Mount(tpath, mountpoint, "", "");
+}
+
+int DiskTool_MkDir(const char *Directory)
+{
+ return -1;
+}
+
+int DiskTool_Copy(const char *Source, const char *Destination)
+{
+ int src = DiskTool_int_TranslateOpen(Source, VFS_OPENFLAG_READ);
+ if( src == -1 ) {
+ Log_Error("DiskTool", "Unable to open %s for reading", Source);
+ return -1;
+ }
+ int dst = DiskTool_int_TranslateOpen(Destination, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_CREATE);
+ if( dst == -1 ) {
+ Log_Error("DiskTool", "Unable to open %s for writing", Destination);
+ VFS_Close(src);
+ return -1;
+ }
+
+ char buf[1024];
+ size_t len, total = 0;
+ while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
+ VFS_Write(dst, len, buf);
+ total += len;
+ }
+ VFS_Write(dst, len, buf), total += len;
+
+ Log_Notice("DiskTool", "Copied %i from %s to %s", total, Source, Destination);
+
+ VFS_Close(dst);
+ VFS_Close(src);
+
+ return 0;
+}
+
+int DiskTool_ListDirectory(const char *Directory)
+{
+ int fd = DiskTool_int_TranslateOpen(Directory, VFS_OPENFLAG_READ|VFS_OPENFLAG_DIRECTORY);
+ if(fd == -1) {
+// fprintf(stderr, "Can't open '%s'\n", Directory);
+ return -1;
+ }
+
+ Log("Directory listing of '%s'", Directory);
+
+ char name[256];
+ while( VFS_ReadDir(fd, name) )
+ {
+ tFInfo fi;
+ int child = VFS_OpenChild(fd, name, 0);
+ if( child != -1 )
+ {
+ VFS_FInfo(child, &fi, 0);
+ VFS_Close(child);
+ }
+ Log("- %02x %6lli %s", fi.flags, fi.size, name);
+ }
+
+ VFS_Close(fd);
+
+ return 0;
+}
+
+int DiskTool_Cat(const char *File)
+{
+ int src = DiskTool_int_TranslateOpen(File, VFS_OPENFLAG_READ);
+ if( src == -1 ) {
+ Log_Error("DiskTool", "Unable to open %s for reading", File);
+ return -1;
+ }
+
+ char buf[1024];
+ size_t len, total = 0;
+ while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
+ _fwrite_stdout(len, buf);
+ total += len;
+ }
+ _fwrite_stdout(len, buf);
+ total += len;
+
+ Log_Notice("DiskTool", "%i bytes from %s", total, File);
+
+ VFS_Close(src);
+ return 0;
+}
+
+int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest)
+{
+ return VFS_ReadAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
+}
+int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest)
+{
+ return VFS_WriteAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
+}
+void DiskTool_LVM_Cleanup(void *Handle)
+{
+ VFS_Close( (int)(tVAddr)Handle );
+}
+
+// --- Internal helpers ---
+int DiskTool_int_TranslateOpen(const char *File, int Flags)
+{
+ size_t tpath_len = DiskTool_int_TranslatePath(NULL, File);
+ if(tpath_len == 0)
+ return -1;
+ char tpath[tpath_len-1];
+ DiskTool_int_TranslatePath(tpath, File);
+
+ return VFS_Open(tpath, Flags);
+}
+
--- /dev/null
+/*
+ * Acess2 DiskTool
+ * - By John Hodge (thePowersGang)
+ *
+ * helpers.c
+ */
+#include <stdlib.h>
+#include <acess_logging.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+
+// === GLOBALS ===
+char gsWorkingDirectory[1024];
+
+
+// === CODE ===
+size_t DiskTool_int_TranslatePath(char *Buffer, const char *Path)
+{
+ int len;
+ const char *colon = strchr(Path, ':');
+
+ if( Path[0] == '#' )
+ {
+ len = strlen(Path+1);
+ if(Buffer) {
+ strcpy(Buffer, Path+1);
+ }
+ }
+ else if( Path[0] == ':' )
+ {
+ len = strlen("/Devices/LVM/");
+ len += strlen(Path+1);
+ if(Buffer) {
+ strcpy(Buffer, "/Devices/LVM/");
+ strcat(Buffer, Path+1);
+ }
+ }
+ else if( colon )
+ {
+ const char *pos;
+ for(pos = Path; pos < colon; pos ++)
+ {
+ if( !isalpha(*pos) )
+ goto native_path;
+ }
+
+ len = strlen("/Mount/");
+ len += strlen(Path);
+ if( Buffer ) {
+ strcpy(Buffer, "/Mount/");
+ strncat(Buffer+strlen("/Mount/"), Path, colon - Path);
+ strcat(Buffer, colon + 1);
+ }
+ }
+ else
+ {
+ native_path:
+ if( !gsWorkingDirectory[0] ) {
+ getcwd(gsWorkingDirectory, 1024);
+ }
+
+ len = strlen("/Native");
+ len += strlen( gsWorkingDirectory ) + 1;
+ len += strlen(Path);
+ if( Buffer ) {
+ strcpy(Buffer, "/Native");
+ strcat(Buffer, gsWorkingDirectory);
+ strcat(Buffer, "/");
+ strcat(Buffer, Path);
+ }
+ }
+ return len;
+}
--- /dev/null
+/*
+ * Acess2 DiskTool utility
+ * - By John Hodge (thePowersGang)
+ *
+ * include/acess.h
+ * - Mock kernel core header
+ */
+#ifndef _DISKTOOL__ACESS_H_
+#define _DISKTOOL__ACESS_H_
+
+#define CONCAT(x,y) x ## y
+#define EXPAND_CONCAT(x,y) CONCAT(x,y)
+#define STR(x) #x
+#define EXPAND_STR(x) STR(x)
+
+#define ASSERT(x) do{}while(0)
+
+extern char __buildnum[];
+#define BUILD_NUM ((int)(Uint)&__buildnum)
+extern const char gsGitHash[];
+extern const char gsBuildInfo[];
+
+#define BITS 32
+#define NULL ((void*)0)
+#include <stdint.h>
+
+typedef uintptr_t Uint;
+//typedef unsigned int size_t;
+#include <stddef.h>
+typedef uint64_t off_t;
+typedef char BOOL;
+
+
+typedef uint8_t Uint8;
+typedef uint16_t Uint16;
+typedef uint32_t Uint32;
+typedef uint64_t Uint64;
+
+typedef int8_t Sint8;
+typedef int16_t Sint16;
+typedef int32_t Sint32;
+typedef int64_t Sint64;
+
+typedef uintptr_t tVAddr;
+typedef uint32_t tPAddr;
+
+typedef uint32_t tUID;
+typedef uint32_t tGID;
+typedef uint32_t tTID;
+
+// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
+typedef char tShortSpinlock;
+
+typedef int64_t tTime;
+extern tTime now(void);
+extern int64_t timestamp(int sec, int min, int hr, int day, int month, int year);
+extern void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms);
+
+#define PACKED __attribute__((packed))
+#define DEPRECATED
+#define EXPORT(s)
+#define EXPORTV(s)
+
+#include <vfs_ext.h>
+
+// These are actually library functions, but they can't be included, so they're defined manually
+extern void *malloc(size_t bytes);
+extern void *calloc(size_t nmemb, size_t size);
+extern void *realloc(void *oldptr, size_t bytes);
+extern void free(void *buffer);
+
+#include <errno.h>
+#include <acess_logging.h>
+
+// Threads
+extern int *Threads_GetErrno(void);
+//extern tPGID Threads_GetPGID(void);
+//extern tPID Threads_GetPID(void);
+extern tTID Threads_GetTID(void);
+extern tUID Threads_GetUID(void);
+extern tGID Threads_GetGID(void);
+
+// Kinda hacky way of not colliding with native errno
+#define errno (*(Threads_GetErrno()))
+
+/**
+ * \name Endianness Swapping
+ * \{
+ */
+#ifdef __BIG_ENDIAN__
+#define LittleEndian16(_val) SwapEndian16(_val)
+#define LittleEndian32(_val) SwapEndian32(_val)
+#define LittleEndian64(_val) SwapEndian32(_val)
+#define BigEndian16(_val) (_val)
+#define BigEndian32(_val) (_val)
+#define BigEndian64(_val) (_val)
+#else
+#define LittleEndian16(_val) (_val)
+#define LittleEndian32(_val) (_val)
+#define LittleEndian64(_val) (_val)
+#define BigEndian16(_val) SwapEndian16(_val)
+#define BigEndian32(_val) SwapEndian32(_val)
+#define BigEndian64(_val) SwapEndian64(_val)
+#endif
+extern Uint16 SwapEndian16(Uint16 Val);
+extern Uint32 SwapEndian32(Uint32 Val);
+extern Uint64 SwapEndian64(Uint64 Val);
+/**
+ * \}
+ */
+
+
+#include <string.h>
+extern int strucmp(const char *s1, const char *s2);
+extern int strpos(const char *Str, char Ch);
+extern void itoa(char *buf, uint64_t num, int base, int minLength, char pad);
+extern int snprintf(char *buf, size_t len, const char *fmt, ...);
+extern int sprintf(char *buf, const char *fmt, ...);
+extern int ReadUTF8(const Uint8 *str, Uint32 *Val);
+extern int WriteUTF8(Uint8 *str, Uint32 Val);
+#define CheckString(str) (1)
+#define CheckMem(mem,sz) (1)
+#include <ctype.h>
+
+// TODO: Move out?
+extern int DivUp(int value, int divisor);
+extern uint64_t DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem);
+
+static inline void SHORTLOCK(tShortSpinlock *Lock) {
+ if(*Lock) Log_KernelPanic("---", "Double short lock");
+ *Lock = 1;
+}
+static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
+
+static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
+
+#endif
+
--- /dev/null
+
+#ifndef _DISKTOOL__ACESS_LOGGING_H_
+#define _DISKTOOL__ACESS_LOGGING_H_
+
+#if DEBUG
+# define ENTER(str, v...) Debug_TraceEnter(__func__, str, ##v)
+# define LOG(fmt, v...) Debug_TraceLog(__func__, fmt, ##v)
+# define LEAVE(t, v...) Debug_TraceLeave(__func__, t, ##v)
+# define LEAVE_RET(t,v) do{LEAVE('-');return v;}while(0)
+#else
+# define ENTER(...) do{}while(0)
+# define LOG(...) do{}while(0)
+# define LEAVE(...) do{}while(0)
+# define LEAVE_RET(t,v) return v;
+#endif
+
+extern void Log_KernelPanic(const char *Ident, const char *Message, ...) __attribute__((noreturn));
+extern void Log_Panic(const char *Ident, const char *Message, ...);
+extern void Log_Error(const char *Ident, const char *Message, ...);
+extern void Log_Warning(const char *Ident, const char *Message, ...);
+extern void Log_Notice(const char *Ident, const char *Message, ...);
+extern void Log_Log(const char *Ident, const char *Message, ...);
+extern void Log_Debug(const char *Ident, const char *Message, ...);
+
+extern void Warning(const char *Message, ...);
+extern void Log(const char *Message, ...);
+extern void Debug_HexDump(const char *Prefix, const void *Data, size_t Length);
+
+extern void Debug_TraceEnter(const char *Function, const char *Format, ...);
+extern void Debug_TraceLog(const char *Function, const char *Format, ...);
+extern void Debug_TraceLeave(const char *Function, char Type, ...);
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 DiskTool
+ * - By John Hodge (thePowersGang)
+ *
+ * include/disktool_common.h
+ * - DiskTool internal API between native and kernel code
+ */
+#ifndef _INCLUDE__DISKTOOL_COMMON_H_
+#define _INCLUDE__DISKTOOL_COMMON_H_
+
+extern void DiskTool_Cleanup(void);
+
+extern int DiskTool_RegisterLVM(const char *Identifier, const char *Path);
+extern int DiskTool_MountImage(const char *Identifier, const char *Path);
+extern int DiskTool_Copy(const char *Source, const char *Destination);
+extern int DiskTool_ListDirectory(const char *Directory);
+extern int DiskTool_Cat(const char *File);
+
+extern size_t DiskTool_int_TranslatePath(char *Buffer, const char *Path);
+
+extern size_t _fwrite_stdout(size_t bytes, const void *data);
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 DiskTool
+ * - By John Hodge (thePowersGang)
+ *
+ * include/modules.h
+ * - Reimplimentation of kernel module interface for POSIX userland
+ */
+#ifndef _INCLUDE__MODULES_H_
+#define _INCLUDE__MODULES_H_
+
+enum
+{
+ MODULE_ERR_OK,
+};
+
+#define MODULE_DEFINE(flags, version, name, init, deinit, deps...) \
+void __init_##init(void) __attribute__((constructor(200))); void __init_##init(void){init(NULL);}
+
+#endif
+
--- /dev/null
+
+#ifndef _MUTEX_H_
+#define _MUTEX_H_
+
+typedef struct {
+ void *LockerReturnAddr;
+} tMutex;
+
+static inline int Mutex_Acquire(tMutex *m) {
+ if(m->LockerReturnAddr)
+ Log_KernelPanic("---", "Double mutex lock of %p by %p (was locked by %p)",
+ m, __builtin_return_address(0), m->LockerReturnAddr);
+ m->LockerReturnAddr = __builtin_return_address(0);;
+ return 0;
+}
+static inline void Mutex_Release(tMutex *m) { m->LockerReturnAddr = 0; }
+
+#endif
+
--- /dev/null
+/*
+ * Acess2 Disk Tool
+ */
+#ifndef _RWLOCK_H
+#define _RWLOCK_H
+
+typedef char tRWLock;
+
+static inline int RWLock_AcquireRead(tRWLock *m) {
+ if(*m) Log_KernelPanic("---", "Double mutex lock");
+ *m = 1;
+ return 0;
+}
+static inline int RWLock_AcquireWrite(tRWLock *m) {
+ if(*m) Log_KernelPanic("---", "Double mutex lock");
+ *m = 1;
+ return 0;
+}
+static inline void RWLock_Release(tRWLock *m) { *m = 0; }
+
+#endif
+
--- /dev/null
+/*
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+#include <disktool_common.h>
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+ // Parse arguments
+ for( int i = 1; i < argc; i ++ )
+ {
+ if( strcmp("mount", argv[i]) == 0 || strcmp("-i", argv[i]) == 0 ) {
+ // Mount an image
+ if( argc - i < 3 ) {
+ fprintf(stderr, "mount takes 2 arguments (image and mountpoint)\n");
+ exit(-1);
+ }
+
+ if( DiskTool_MountImage(argv[i+2], argv[i+1]) ) {
+ fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[i+1], argv[i+2]);
+ break;
+ }
+
+ i += 2;
+ continue ;
+ }
+
+ if( strcmp("mountlvm", argv[i]) == 0 || strcmp("lvm", argv[i]) == 0 ) {
+
+ if( argc - i < 3 ) {
+ fprintf(stderr, "lvm takes 2 arguments (iamge and ident)\n");
+ exit(-1);
+ }
+
+ if( DiskTool_RegisterLVM(argv[i+2], argv[i+1]) ) {
+ fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[i+1], argv[i+2]);
+ break;
+ }
+
+ i += 2;
+ continue ;
+ }
+
+ if( strcmp("ls", argv[i]) == 0 ) {
+ if( argc - i < 2 ) {
+ fprintf(stderr, "ls takes 1 argument (path)\n");
+ break;
+ }
+
+ DiskTool_ListDirectory(argv[i+1]);
+ i += 1;
+ continue ;
+ }
+
+ if( strcmp("cp", argv[i]) == 0 ) {
+
+ if( argc - i < 3 ) {
+ fprintf(stderr, "cp takes 2 arguments (source and destination)\n");
+ break;
+ }
+
+ DiskTool_Copy(argv[i+1], argv[i+2]);
+
+ i += 2;
+ continue ;
+ }
+
+ if( strcmp("cat", argv[i]) == 0 ) {
+
+ if( argc - 1 < 2 ) {
+ fprintf(stderr, "cat takes 1 argument (path)\n");
+ break;
+ }
+
+ DiskTool_Cat(argv[i+1]);
+
+ i += 1;
+ continue;
+ }
+
+ fprintf(stderr, "Unknown command '%s'\n", argv[i]);
+ }
+
+ DiskTool_Cleanup();
+
+ return 0;
+}
+
+// NOTE: This is in a native compiled file because it needs access to the real errno macro
+int *Threads_GetErrno(void)
+{
+ return &errno;
+}
+
+size_t _fwrite_stdout(size_t bytes, const void *data)
+{
+ return fwrite(data, bytes, 1, stdout);
+}
--- /dev/null
+../../AcessNative/acesskernel_src/nativefs.c
\ No newline at end of file
+++ /dev/null
-
-TARGET := $(shell gcc -v 2>&1 | grep Targ | awk '{print $$2}')
-
-include ../../../Makefile.Version.cfg
--include Makefile.BuildNum
-ifeq ($(BUILD_NUM),)
-BUILD_NUM = 1
-endif
-
-
-KERNEL_SRC = ../../../KernelLand/Kernel/
-MODULE_SRC = ../../../KernelLand/Modules/
-
-BIN = ../DiskTool
-# Kernel Sources (compiled with -ffreestanding)
-K_OBJ := lib.o
-K_OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/io.o vfs/dir.o
-K_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o # vfs/select.o
-K_OBJ += vfs/fs/root.o vfs/fs/devfs.o
-K_OBJ += drvutil_disk.o drv/proc.o
-# Modules
-MODULES := Storage/LVM Filesystems/FAT Filesystems/Ext2 Filesystems/NTFS
-# Local kernel soruces (same as above, but located in same directory as Makefile)
-L_OBJ = vfs_handles.o threads.o nativefs.o time.o actions.o
-# Native Sources (compiled as usual)
-N_OBJ = main.o script.o logging.o helpers.o
-
-# Compilation Options
-CFLAGS := -Wall -std=gnu99 -g -Werror
-CPPFLAGS := -I include/
-K_CPPFLAGS := -I $(KERNEL_SRC)include -I $(MODULE_SRC)
-LDFLAGS += -Wl,--defsym,__buildnum=$(BUILD_NUM) -g
-
-BUILDINFO_OBJ := obj/$(TARGET)/buildinfo.o
-BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c)
-
-# ====================
-# == Start of Magic ==
-# ====================
-# -- Load modules ---
-$(foreach module,$(MODULES), $(eval include $(MODULE_SRC)$(module)/Makefile) $(eval M_OBJ += $(addprefix $(module)/,$(OBJ))) )
-
-# -- Apply Prefixes to object paths
-OBJ_PREFIX = obj/$(TARGET)/
-K_OBJ_PREFIX = $(OBJ_PREFIX)_Kernel/
-M_OBJ_PREFIX = $(OBJ_PREFIX)_Module/
-K_OBJ := $(addprefix $(K_OBJ_PREFIX),$(K_OBJ))
-M_OBJ := $(addprefix $(M_OBJ_PREFIX),$(M_OBJ))
-L_OBJ := $(addprefix $(OBJ_PREFIX),$(L_OBJ))
-N_OBJ := $(addprefix $(OBJ_PREFIX),$(N_OBJ))
-
-OBJ := $(N_OBJ) $(L_OBJ) $(K_OBJ) $(M_OBJ) $(BUILDINFO_OBJ)
-
-DEPFILES = $(filter %.o,$(OBJ))
-DEPFILES := $(DEPFILES:%=%.dep)
-
-
-.PHONY: all clean
-
-all: $(BIN)
-
-clean:
- $(RM) -f $(OBJ) $(DEPFILES) $(BIN)
-
-$(BIN): $(OBJ)
- @echo [CC Link] -o $(BIN)
- @$(CC) -o $(BIN) $(OBJ) $(LDFLAGS)
- @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum
-
-$(M_OBJ): $(M_OBJ_PREFIX)%.o: $(MODULE_SRC)%.c
- @mkdir -p $(dir $@)
- @echo [CC Module] -o $@
- @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
-
-$(K_OBJ): $(K_OBJ_PREFIX)%.o: $(KERNEL_SRC)%.c
- @mkdir -p $(dir $@)
- @echo [CC Kernel] -o $@
- @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
-
-$(L_OBJ): $(OBJ_PREFIX)%.o: %.c
- @mkdir -p $(dir $@)
- @echo [CC Local] -o $@
- @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
-
-$(N_OBJ): $(OBJ_PREFIX)%.o: %.c
- @mkdir -p $(dir $@)
- @echo [CC Native] -o $@
-
-# Hacky buildinfo.c file
-$(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile
- @echo "" > $@
- @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@
- @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@
- @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@
- @echo "const char gsBuildInfo[] = \"Acess2 DiskTool v$(ACESS_VERSION)\";" >> $@
-$(BUILDINFO_OBJ): $(BUILDINFO_SRC)
- @echo [CC] -o $@
- @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
-
-$(OBJ): Makefile
-
--include $(DEPFILES)
+++ /dev/null
-/*
- * Acess2 DiskTool
- * - By John Hodge (thePowersGang)
- *
- * actions.c
- * - High level actions that call the VFS
- * # Kernel-space compiled
- */
-#include <acess.h>
-#include <disktool_common.h>
-#include <Storage/LVM/include/lvm.h>
-
-// === IMPORTS ===
-extern int NativeFS_Install(char **Arguments);
-extern int LVM_Cleanup(void);
-
-// === PROTOTYPES ===
-void DiskTool_Initialise(void) __attribute__((constructor(101)));
-void DiskTool_Cleanup(void);
- int DiskTool_int_TranslateOpen(const char *File, int Mode);
- int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest);
- int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest);
-void DiskTool_LVM_Cleanup(void *Handle);
-
-// === GLOBALS ===
-tLVM_VolType gDiskTool_VolumeType = {
- .Name = "DiskTool",
- .Read = DiskTool_LVM_Read,
- .Write = DiskTool_LVM_Write,
- .Cleanup = DiskTool_LVM_Cleanup
-};
-
-// === CODE ===
-void DiskTool_Initialise(void)
-{
- VFS_Init();
- NativeFS_Install(NULL);
- VFS_MkDir("/Native");
- VFS_Mount("/", "/Native", "nativefs", "");
-}
-
-void DiskTool_Cleanup(void)
-{
- int vfs_rv, lvm_rv;
- int nNochangeLoop = 0;
- // Unmount all
- do {
- lvm_rv = LVM_Cleanup();
- vfs_rv = VFS_UnmountAll();
- Log_Debug("DiskTool", "Unmounted %i volumes", vfs_rv);
- if( vfs_rv == 0 && lvm_rv == 0 ) {
- nNochangeLoop ++;
- if(nNochangeLoop == 2) {
- Log_Error("DiskTool", "Possible handle leak");
- break;
- }
- }
- else {
- nNochangeLoop = 0;
- }
- }
- while( vfs_rv >= 0 || lvm_rv != 0 );
-}
-
-int DiskTool_RegisterLVM(const char *Identifier, const char *Path)
-{
- int fd = DiskTool_int_TranslateOpen(Path, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
- if(fd == -1) {
- Log_Notice("DiskTool", "Can't open '%s' for LVM %s", Path, Identifier);
- return -1;
- }
- VFS_Seek(fd, 0, SEEK_END);
- LVM_AddVolume( &gDiskTool_VolumeType, Identifier, (void*)(tVAddr)fd, 512, VFS_Tell(fd)/512);
- Log_Debug("DiskTool", "Registered '%s' for LVM %s", Path, Identifier);
- return 0;
-}
-
-int DiskTool_MountImage(const char *Identifier, const char *Path)
-{
- // Validate Identifier and make mountpoint string
- char mountpoint[sizeof("/Mount/") + strlen(Identifier) + 1];
- strcpy(mountpoint, "/Mount/");
- strcat(mountpoint, Identifier);
-
- // Translate path
- size_t tpath_len = DiskTool_int_TranslatePath(NULL, Path);
- char tpath[tpath_len-1];
- DiskTool_int_TranslatePath(tpath, Path);
-
- // Call mount
- VFS_MkDir(mountpoint);
- // TODO: Detect filesystem?
- return VFS_Mount(tpath, mountpoint, "", "");
-}
-
-int DiskTool_MkDir(const char *Directory)
-{
- return -1;
-}
-
-int DiskTool_Copy(const char *Source, const char *Destination)
-{
- int src = DiskTool_int_TranslateOpen(Source, VFS_OPENFLAG_READ);
- if( src == -1 ) {
- Log_Error("DiskTool", "Unable to open %s for reading", Source);
- return -1;
- }
- int dst = DiskTool_int_TranslateOpen(Destination, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_CREATE);
- if( dst == -1 ) {
- Log_Error("DiskTool", "Unable to open %s for writing", Destination);
- VFS_Close(src);
- return -1;
- }
-
- char buf[1024];
- size_t len, total = 0;
- while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
- VFS_Write(dst, len, buf);
- total += len;
- }
- VFS_Write(dst, len, buf), total += len;
-
- Log_Notice("DiskTool", "Copied %i from %s to %s", total, Source, Destination);
-
- VFS_Close(dst);
- VFS_Close(src);
-
- return 0;
-}
-
-int DiskTool_ListDirectory(const char *Directory)
-{
- int fd = DiskTool_int_TranslateOpen(Directory, VFS_OPENFLAG_READ|VFS_OPENFLAG_DIRECTORY);
- if(fd == -1) {
-// fprintf(stderr, "Can't open '%s'\n", Directory);
- return -1;
- }
-
- Log("Directory listing of '%s'", Directory);
-
- char name[256];
- while( VFS_ReadDir(fd, name) )
- {
- tFInfo fi;
- int child = VFS_OpenChild(fd, name, 0);
- if( child != -1 )
- {
- VFS_FInfo(child, &fi, 0);
- VFS_Close(child);
- }
- Log("- %02x %6lli %s", fi.flags, fi.size, name);
- }
-
- VFS_Close(fd);
-
- return 0;
-}
-
-int DiskTool_Cat(const char *File)
-{
- int src = DiskTool_int_TranslateOpen(File, VFS_OPENFLAG_READ);
- if( src == -1 ) {
- Log_Error("DiskTool", "Unable to open %s for reading", File);
- return -1;
- }
-
- char buf[1024];
- size_t len, total = 0;
- while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
- _fwrite_stdout(len, buf);
- total += len;
- }
- _fwrite_stdout(len, buf);
- total += len;
-
- Log_Notice("DiskTool", "%i bytes from %s", total, File);
-
- VFS_Close(src);
- return 0;
-}
-
-int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest)
-{
- return VFS_ReadAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
-}
-int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest)
-{
- return VFS_WriteAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
-}
-void DiskTool_LVM_Cleanup(void *Handle)
-{
- VFS_Close( (int)(tVAddr)Handle );
-}
-
-// --- Internal helpers ---
-int DiskTool_int_TranslateOpen(const char *File, int Flags)
-{
- size_t tpath_len = DiskTool_int_TranslatePath(NULL, File);
- if(tpath_len == 0)
- return -1;
- char tpath[tpath_len-1];
- DiskTool_int_TranslatePath(tpath, File);
-
- return VFS_Open(tpath, Flags);
-}
-
+++ /dev/null
-/*
- * Acess2 DiskTool
- * - By John Hodge (thePowersGang)
- *
- * helpers.c
- */
-#include <stdlib.h>
-#include <acess_logging.h>
-#include <ctype.h>
-#include <string.h>
-#include <unistd.h>
-
-// === GLOBALS ===
-char gsWorkingDirectory[1024];
-
-
-// === CODE ===
-size_t DiskTool_int_TranslatePath(char *Buffer, const char *Path)
-{
- int len;
- const char *colon = strchr(Path, ':');
-
- if( Path[0] == '#' )
- {
- len = strlen(Path+1);
- if(Buffer) {
- strcpy(Buffer, Path+1);
- }
- }
- else if( Path[0] == ':' )
- {
- len = strlen("/Devices/LVM/");
- len += strlen(Path+1);
- if(Buffer) {
- strcpy(Buffer, "/Devices/LVM/");
- strcat(Buffer, Path+1);
- }
- }
- else if( colon )
- {
- const char *pos;
- for(pos = Path; pos < colon; pos ++)
- {
- if( !isalpha(*pos) )
- goto native_path;
- }
-
- len = strlen("/Mount/");
- len += strlen(Path);
- if( Buffer ) {
- strcpy(Buffer, "/Mount/");
- strncat(Buffer+strlen("/Mount/"), Path, colon - Path);
- strcat(Buffer, colon + 1);
- }
- }
- else
- {
- native_path:
- if( !gsWorkingDirectory[0] ) {
- getcwd(gsWorkingDirectory, 1024);
- }
-
- len = strlen("/Native");
- len += strlen( gsWorkingDirectory ) + 1;
- len += strlen(Path);
- if( Buffer ) {
- strcpy(Buffer, "/Native");
- strcat(Buffer, gsWorkingDirectory);
- strcat(Buffer, "/");
- strcat(Buffer, Path);
- }
- }
- return len;
-}
+++ /dev/null
-/*
- * Acess2 DiskTool utility
- * - By John Hodge (thePowersGang)
- *
- * include/acess.h
- * - Mock kernel core header
- */
-#ifndef _DISKTOOL__ACESS_H_
-#define _DISKTOOL__ACESS_H_
-
-#define CONCAT(x,y) x ## y
-#define EXPAND_CONCAT(x,y) CONCAT(x,y)
-#define STR(x) #x
-#define EXPAND_STR(x) STR(x)
-
-#define ASSERT(x) do{}while(0)
-
-extern char __buildnum[];
-#define BUILD_NUM ((int)(Uint)&__buildnum)
-extern const char gsGitHash[];
-extern const char gsBuildInfo[];
-
-#define BITS 32
-#define NULL ((void*)0)
-#include <stdint.h>
-
-typedef uintptr_t Uint;
-//typedef unsigned int size_t;
-#include <stddef.h>
-typedef uint64_t off_t;
-typedef char BOOL;
-
-
-typedef uint8_t Uint8;
-typedef uint16_t Uint16;
-typedef uint32_t Uint32;
-typedef uint64_t Uint64;
-
-typedef int8_t Sint8;
-typedef int16_t Sint16;
-typedef int32_t Sint32;
-typedef int64_t Sint64;
-
-typedef uintptr_t tVAddr;
-typedef uint32_t tPAddr;
-
-typedef uint32_t tUID;
-typedef uint32_t tGID;
-typedef uint32_t tTID;
-
-// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
-typedef char tShortSpinlock;
-
-typedef int64_t tTime;
-extern tTime now(void);
-extern int64_t timestamp(int sec, int min, int hr, int day, int month, int year);
-extern void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms);
-
-#define PACKED __attribute__((packed))
-#define DEPRECATED
-#define EXPORT(s)
-#define EXPORTV(s)
-
-#include <vfs_ext.h>
-
-// These are actually library functions, but they can't be included, so they're defined manually
-extern void *malloc(size_t bytes);
-extern void *calloc(size_t nmemb, size_t size);
-extern void *realloc(void *oldptr, size_t bytes);
-extern void free(void *buffer);
-
-#include <errno.h>
-#include <acess_logging.h>
-
-// Threads
-extern int *Threads_GetErrno(void);
-//extern tPGID Threads_GetPGID(void);
-//extern tPID Threads_GetPID(void);
-extern tTID Threads_GetTID(void);
-extern tUID Threads_GetUID(void);
-extern tGID Threads_GetGID(void);
-
-// Kinda hacky way of not colliding with native errno
-#define errno (*(Threads_GetErrno()))
-
-/**
- * \name Endianness Swapping
- * \{
- */
-#ifdef __BIG_ENDIAN__
-#define LittleEndian16(_val) SwapEndian16(_val)
-#define LittleEndian32(_val) SwapEndian32(_val)
-#define LittleEndian64(_val) SwapEndian32(_val)
-#define BigEndian16(_val) (_val)
-#define BigEndian32(_val) (_val)
-#define BigEndian64(_val) (_val)
-#else
-#define LittleEndian16(_val) (_val)
-#define LittleEndian32(_val) (_val)
-#define LittleEndian64(_val) (_val)
-#define BigEndian16(_val) SwapEndian16(_val)
-#define BigEndian32(_val) SwapEndian32(_val)
-#define BigEndian64(_val) SwapEndian64(_val)
-#endif
-extern Uint16 SwapEndian16(Uint16 Val);
-extern Uint32 SwapEndian32(Uint32 Val);
-extern Uint64 SwapEndian64(Uint64 Val);
-/**
- * \}
- */
-
-
-#include <string.h>
-extern int strucmp(const char *s1, const char *s2);
-extern int strpos(const char *Str, char Ch);
-extern void itoa(char *buf, uint64_t num, int base, int minLength, char pad);
-extern int snprintf(char *buf, size_t len, const char *fmt, ...);
-extern int sprintf(char *buf, const char *fmt, ...);
-extern int ReadUTF8(const Uint8 *str, Uint32 *Val);
-extern int WriteUTF8(Uint8 *str, Uint32 Val);
-#define CheckString(str) (1)
-#define CheckMem(mem,sz) (1)
-#include <ctype.h>
-
-// TODO: Move out?
-extern int DivUp(int value, int divisor);
-extern uint64_t DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem);
-
-static inline void SHORTLOCK(tShortSpinlock *Lock) {
- if(*Lock) Log_KernelPanic("---", "Double short lock");
- *Lock = 1;
-}
-static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
-
-static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
-
-#endif
-
+++ /dev/null
-
-#ifndef _DISKTOOL__ACESS_LOGGING_H_
-#define _DISKTOOL__ACESS_LOGGING_H_
-
-#if DEBUG
-# define ENTER(str, v...) Debug_TraceEnter(__func__, str, ##v)
-# define LOG(fmt, v...) Debug_TraceLog(__func__, fmt, ##v)
-# define LEAVE(t, v...) Debug_TraceLeave(__func__, t, ##v)
-# define LEAVE_RET(t,v) do{LEAVE('-');return v;}while(0)
-#else
-# define ENTER(...) do{}while(0)
-# define LOG(...) do{}while(0)
-# define LEAVE(...) do{}while(0)
-# define LEAVE_RET(t,v) return v;
-#endif
-
-extern void Log_KernelPanic(const char *Ident, const char *Message, ...) __attribute__((noreturn));
-extern void Log_Panic(const char *Ident, const char *Message, ...);
-extern void Log_Error(const char *Ident, const char *Message, ...);
-extern void Log_Warning(const char *Ident, const char *Message, ...);
-extern void Log_Notice(const char *Ident, const char *Message, ...);
-extern void Log_Log(const char *Ident, const char *Message, ...);
-extern void Log_Debug(const char *Ident, const char *Message, ...);
-
-extern void Warning(const char *Message, ...);
-extern void Log(const char *Message, ...);
-extern void Debug_HexDump(const char *Prefix, const void *Data, size_t Length);
-
-extern void Debug_TraceEnter(const char *Function, const char *Format, ...);
-extern void Debug_TraceLog(const char *Function, const char *Format, ...);
-extern void Debug_TraceLeave(const char *Function, char Type, ...);
-
-#endif
-
+++ /dev/null
-/*
- * Acess2 DiskTool
- * - By John Hodge (thePowersGang)
- *
- * include/disktool_common.h
- * - DiskTool internal API between native and kernel code
- */
-#ifndef _INCLUDE__DISKTOOL_COMMON_H_
-#define _INCLUDE__DISKTOOL_COMMON_H_
-
-extern void DiskTool_Cleanup(void);
-
-extern int DiskTool_RegisterLVM(const char *Identifier, const char *Path);
-extern int DiskTool_MountImage(const char *Identifier, const char *Path);
-extern int DiskTool_Copy(const char *Source, const char *Destination);
-extern int DiskTool_ListDirectory(const char *Directory);
-extern int DiskTool_Cat(const char *File);
-
-extern size_t DiskTool_int_TranslatePath(char *Buffer, const char *Path);
-
-extern size_t _fwrite_stdout(size_t bytes, const void *data);
-
-#endif
-
+++ /dev/null
-/*
- * Acess2 DiskTool
- * - By John Hodge (thePowersGang)
- *
- * include/modules.h
- * - Reimplimentation of kernel module interface for POSIX userland
- */
-#ifndef _INCLUDE__MODULES_H_
-#define _INCLUDE__MODULES_H_
-
-enum
-{
- MODULE_ERR_OK,
-};
-
-#define MODULE_DEFINE(flags, version, name, init, deinit, deps...) \
-void __init_##init(void) __attribute__((constructor(200))); void __init_##init(void){init(NULL);}
-
-#endif
-
+++ /dev/null
-
-#ifndef _MUTEX_H_
-#define _MUTEX_H_
-
-typedef struct {
- void *LockerReturnAddr;
-} tMutex;
-
-static inline int Mutex_Acquire(tMutex *m) {
- if(m->LockerReturnAddr)
- Log_KernelPanic("---", "Double mutex lock of %p by %p (was locked by %p)",
- m, __builtin_return_address(0), m->LockerReturnAddr);
- m->LockerReturnAddr = __builtin_return_address(0);;
- return 0;
-}
-static inline void Mutex_Release(tMutex *m) { m->LockerReturnAddr = 0; }
-
-#endif
-
+++ /dev/null
-/*
- * Acess2 Disk Tool
- */
-#ifndef _RWLOCK_H
-#define _RWLOCK_H
-
-typedef char tRWLock;
-
-static inline int RWLock_AcquireRead(tRWLock *m) {
- if(*m) Log_KernelPanic("---", "Double mutex lock");
- *m = 1;
- return 0;
-}
-static inline int RWLock_AcquireWrite(tRWLock *m) {
- if(*m) Log_KernelPanic("---", "Double mutex lock");
- *m = 1;
- return 0;
-}
-static inline void RWLock_Release(tRWLock *m) { *m = 0; }
-
-#endif
-
+++ /dev/null
-/*
- *
- */
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <acess_logging.h>
-#include <ctype.h>
-#include <inttypes.h>
-
-#define LOGHDR(col,type) fprintf(stderr, "\e["col"m[%-8.8s]"type" ", Ident)
-#define LOGTAIL() fprintf(stderr, "\e[0m\n")
-
-#define PUTERR(col,type) {\
- LOGHDR(col,type);\
- va_list args; va_start(args, Message);\
- vfprintf(stderr, Message, args);\
- va_end(args);\
- LOGTAIL();\
-}
-
-// === CODE ===
-void Log_KernelPanic(const char *Ident, const char *Message, ...) {
- PUTERR("35", "k")
- abort();
-}
-void Log_Panic(const char *Ident, const char *Message, ...)
- PUTERR("34", "p")
-void Log_Error(const char *Ident, const char *Message, ...)
- PUTERR("31", "e")
-void Log_Warning(const char *Ident, const char *Message, ...)
- PUTERR("33", "w")
-void Log_Notice(const char *Ident, const char *Message, ...)
- PUTERR("32", "n")
-void Log_Log(const char *Ident, const char *Message, ...)
- PUTERR("37", "l")
-void Log_Debug(const char *Ident, const char *Message, ...)
- PUTERR("37", "d")
-
-void Warning(const char *Message, ...) {
- const char *Ident = "";
- PUTERR("33", "W")
-}
-void Log(const char *Message, ...) {
- const char *Ident = "";
- PUTERR("37", "L")
-}
-
-void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
-{
- const uint8_t *data = Data;
- size_t ofs;
- fprintf(stderr, "[HexDump ]d %s: %i bytes\n", Prefix, (int)Length);
- for( ofs = 0; ofs + 16 <= Length; ofs += 16 )
- {
- fprintf(stderr, "[HexDump ]d %s:", Prefix);
- fprintf(stderr, " %02x %02x %02x %02x %02x %02x %02x %02x",
- data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
- data += 8;
- fprintf(stderr, " %02x %02x %02x %02x %02x %02x %02x %02x",
- data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
- data += 8;
- fprintf(stderr, "\n");
- }
-
- fprintf(stderr, "[HexDump ]d %s:", Prefix);
- for( ; ofs < Length; ofs ++ )
- {
- if( ofs % 8 == 0 ) fprintf(stderr, " ");
- fprintf(stderr, " %02x", data[ofs%16]);
- }
- fprintf(stderr, "\n");
-}
-
- int giDebug_TraceLevel = 0;
-
-void Debug_TraceEnter(const char *Function, const char *Format, ...)
-{
- const char *Ident = "Trace";
- LOGHDR("37","T");
- for( int i = 0; i < giDebug_TraceLevel; i ++ )
- fprintf(stderr, " ");
- fprintf(stderr, "%s: (", Function);
-
- va_list args;
- va_start(args, Format);
-
- int hasBeenPrev = 0;
- while(*Format)
- {
- while( *Format && isblank(*Format) )
- Format ++;
- if( !*Format ) break;
-
- char type = *Format++;
- const char *start = Format;
- while( *Format && !isblank(*Format) )
- Format ++;
-
- if(hasBeenPrev)
- fprintf(stderr, ",");
- hasBeenPrev = 1;
-
- fprintf(stderr, "%.*s=", (int)(Format-start), start);
- switch(type)
- {
- case 'p':
- fprintf(stderr, "%p", va_arg(args,const void *));
- break;
- case 's':
- fprintf(stderr, "\"%s\"", va_arg(args,const char *));
- break;
- case 'i':
- fprintf(stderr, "%i", va_arg(args,int));
- break;
- case 'x':
- fprintf(stderr, "0x%x", va_arg(args,unsigned int));
- break;
- case 'X':
- fprintf(stderr, "0x%"PRIx64, va_arg(args,uint64_t));
- break;
- default:
- va_arg(args,uintptr_t);
- fprintf(stderr, "?");
- break;
- }
- }
-
- va_end(args);
-
- fprintf(stderr, ")");
- LOGTAIL();
- giDebug_TraceLevel ++;
-}
-
-void Debug_TraceLog(const char *Function, const char *Format, ...)
-{
- const char *Ident = "Trace";
- LOGHDR("37","T");
-
- for( int i = 0; i < giDebug_TraceLevel; i ++ )
- fprintf(stderr, " ");
- fprintf(stderr, "%s: ", Function);
-
- va_list args;
- va_start(args, Format);
-
- vfprintf(stderr, Format, args);
-
- va_end(args);
- LOGTAIL();
-}
-
-void Debug_TraceLeave(const char *Function, char Type, ...)
-{
- if( giDebug_TraceLevel == 0 ) {
- Log_Error("Debug", "Function %s called LEAVE without ENTER", Function);
- }
-
- const char *Ident = "Trace";
- LOGHDR("37","T");
-
- va_list args;
- va_start(args, Type);
-
- if( giDebug_TraceLevel > 0 )
- {
- giDebug_TraceLevel --;
- for( int i = 0; i < giDebug_TraceLevel; i ++ )
- fprintf(stderr, " ");
- }
- fprintf(stderr, "%s: RETURN", Function);
- switch(Type)
- {
- case '-':
- break;
- case 'i':
- fprintf(stderr, " %i", va_arg(args, int));
- break;
- case 'x':
- fprintf(stderr, " 0x%x", va_arg(args, unsigned int));
- break;
- case 'X':
- fprintf(stderr, " 0x%"PRIx64, va_arg(args,uint64_t));
- break;
- case 's':
- fprintf(stderr, " \"%s\"", va_arg(args, const char *));
- break;
- case 'p':
- fprintf(stderr, " %p", va_arg(args, const void *));
- break;
- case 'n':
- fprintf(stderr, " NULL");
- break;
- default:
- fprintf(stderr, " ?");
- break;
- }
-
- va_end(args);
- LOGTAIL();
-}
-
+++ /dev/null
-/*
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <stdint.h>
-#include <string.h>
-#include <disktool_common.h>
-
-// === CODE ===
-int main(int argc, char *argv[])
-{
- // Parse arguments
- for( int i = 1; i < argc; i ++ )
- {
- if( strcmp("mount", argv[i]) == 0 || strcmp("-i", argv[i]) == 0 ) {
- // Mount an image
- if( argc - i < 3 ) {
- fprintf(stderr, "mount takes 2 arguments (image and mountpoint)\n");
- exit(-1);
- }
-
- if( DiskTool_MountImage(argv[i+2], argv[i+1]) ) {
- fprintf(stderr, "Unable to mount '%s' as '%s'\n", argv[i+1], argv[i+2]);
- break;
- }
-
- i += 2;
- continue ;
- }
-
- if( strcmp("mountlvm", argv[i]) == 0 || strcmp("lvm", argv[i]) == 0 ) {
-
- if( argc - i < 3 ) {
- fprintf(stderr, "lvm takes 2 arguments (iamge and ident)\n");
- exit(-1);
- }
-
- if( DiskTool_RegisterLVM(argv[i+2], argv[i+1]) ) {
- fprintf(stderr, "Unable to register '%s' as LVM '%s'\n", argv[i+1], argv[i+2]);
- break;
- }
-
- i += 2;
- continue ;
- }
-
- if( strcmp("ls", argv[i]) == 0 ) {
- if( argc - i < 2 ) {
- fprintf(stderr, "ls takes 1 argument (path)\n");
- break;
- }
-
- DiskTool_ListDirectory(argv[i+1]);
- i += 1;
- continue ;
- }
-
- if( strcmp("cp", argv[i]) == 0 ) {
-
- if( argc - i < 3 ) {
- fprintf(stderr, "cp takes 2 arguments (source and destination)\n");
- break;
- }
-
- DiskTool_Copy(argv[i+1], argv[i+2]);
-
- i += 2;
- continue ;
- }
-
- if( strcmp("cat", argv[i]) == 0 ) {
-
- if( argc - 1 < 2 ) {
- fprintf(stderr, "cat takes 1 argument (path)\n");
- break;
- }
-
- DiskTool_Cat(argv[i+1]);
-
- i += 1;
- continue;
- }
-
- fprintf(stderr, "Unknown command '%s'\n", argv[i]);
- }
-
- DiskTool_Cleanup();
-
- return 0;
-}
-
-// NOTE: This is in a native compiled file because it needs access to the real errno macro
-int *Threads_GetErrno(void)
-{
- return &errno;
-}
-
-// TODO: Move into a helper lib?
-void itoa(char *buf, uint64_t num, int base, int minLength, char pad)
-{
- char fmt[] = "%0ll*x";
- switch(base)
- {
- case 8: fmt[5] = 'o'; break;
- case 10: fmt[5] = 'd'; break;
- case 16: fmt[5] = 'x'; break;
- }
- if(pad != '0') {
- fmt[1] = '%';
- sprintf(buf, fmt+1, minLength, num);
- }
- else {
- sprintf(buf, fmt, minLength, num);
- }
-}
-
-int strpos(const char *Str, char Ch)
-{
- const char *r = strchr(Str, Ch);
- if(!r) return -1;
- return r - Str;
-}
-
-int strucmp(const char *s1, const char *s2)
-{
- return strcasecmp(s1, s2);
-}
-
-uint64_t DivMod64U(uint64_t value, uint64_t divisor, uint64_t *remainder)
-{
- if(remainder)
- *remainder = value % divisor;
- return value / divisor;
-}
-
-size_t _fwrite_stdout(size_t bytes, const void *data)
-{
- return fwrite(data, bytes, 1, stdout);
-}
+++ /dev/null
-../../../AcessNative/acesskernel_src/nativefs.c
\ No newline at end of file
+++ /dev/null
-/*
- *
- */
-#include <acess.h>
-#include <threads.h>
-
-// === CODE ===
-tThread *Proc_GetCurThread(void)
-{
- return NULL;
-}
-
-void Threads_PostEvent(tThread *Thread, Uint32 Events)
-{
-
-}
-
-Uint32 Threads_WaitEvents(Uint32 Events)
-{
- Log_KernelPanic("Threads", "Can't use _WaitEvents in DiskTool");
- return 0;
-}
-
-void Threads_ClearEvent(Uint32 Mask)
-{
-
-}
-
-tUID Threads_GetUID(void) { return 0; }
-tGID Threads_GetGID(void) { return 0; }
-
-int *Threads_GetMaxFD(void) { static int max_fd=32; return &max_fd; }
-char **Threads_GetCWD(void) { static char *cwd; return &cwd; }
-char **Threads_GetChroot(void) { static char *chroot; return &chroot; }
-
+++ /dev/null
-/*
- * Acess2 DiskTool
- * - By John Hodge (thePowersGang)
- *
- * time.c
- * - Timing functions (emulated)
- */
-#include <acess.h>
-#include <timers.h>
-
-// === CODE ===
-tTimer *Time_AllocateTimer(tTimerCallback *Callback, void *Argument)
-{
- return NULL;
-}
-
-void Time_ScheduleTimer(tTimer *Timer, int Delta)
-{
-
-}
-
-void Time_FreeTimer(tTimer *Timer)
-{
-
-}
-
-Sint64 now(void)
-{
- // TODO: Translate UNIX time into Acess time
- return 0;
-}
-
+++ /dev/null
-/*
- *
- */
-#include <acess.h>
-#include <vfs.h>
-#include <vfs_int.h>
-
-#define MAX_KERNEL_FILES 32
-
-// === GLOBALS ===
-tVFS_Handle gaKernelHandles[MAX_KERNEL_FILES];
-
-// === CODE ===
-int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
-{
- for( int i = 0; i < MAX_KERNEL_FILES; i ++ )
- {
- if(gaKernelHandles[i].Node) continue;
- gaKernelHandles[i].Node = Node;
- gaKernelHandles[i].Position = 0;
- gaKernelHandles[i].Mode = Mode;
- return i;
- }
-
- return -1;
-}
-
-tVFS_Handle *VFS_GetHandle(int ID)
-{
- if( ID < 0 || ID >= MAX_KERNEL_FILES )
- return NULL;
- return &gaKernelHandles[ID];
-}
--- /dev/null
+/*
+ *
+ */
+#include <acess.h>
+#include <vfs.h>
+#include <vfs_int.h>
+
+#define MAX_KERNEL_FILES 32
+
+// === GLOBALS ===
+tVFS_Handle gaKernelHandles[MAX_KERNEL_FILES];
+
+// === CODE ===
+int VFS_AllocHandle(int bIsUser, tVFS_Node *Node, int Mode)
+{
+ for( int i = 0; i < MAX_KERNEL_FILES; i ++ )
+ {
+ if(gaKernelHandles[i].Node) continue;
+ gaKernelHandles[i].Node = Node;
+ gaKernelHandles[i].Position = 0;
+ gaKernelHandles[i].Mode = Mode;
+ return i;
+ }
+
+ return -1;
+}
+
+tVFS_Handle *VFS_GetHandle(int ID)
+{
+ if( ID < 0 || ID >= MAX_KERNEL_FILES )
+ return NULL;
+ return &gaKernelHandles[ID];
+}
--- /dev/null
+
+TARGET := $(shell gcc -v 2>&1 | grep Targ | awk '{print $$2}')
+
+include ../../Makefile.Version.cfg
+-include Makefile.BuildNum
+ifeq ($(BUILD_NUM),)
+BUILD_NUM = 1
+endif
+
+
+KERNEL_SRC = ../../KernelLand/Kernel/
+MODULE_SRC = ../../KernelLand/Modules/
+
+BIN = ../nettest
+# Kernel Sources (compiled with -ffreestanding)
+K_OBJ := lib.o adt.o
+K_OBJ += vfs/acls.o vfs/io.o vfs/fs/devfs.o
+#K_OBJ += vfs/main.o vfs/open.o vfs/io.o vfs/dir.o
+#K_OBJ += vfs/nodecache.o vfs/mount.o vfs/memfile.o # vfs/select.o
+#K_OBJ += vfs/fs/root.o vfs/fs/devfs.o
+#K_OBJ += drvutil_disk.o drv/proc.o
+# Modules
+MODULES := IPStack
+# Local kernel soruces (same as above, but located in same directory as Makefile)
+L_OBJ = vfs_shim.o nic.o tcpclient.o tcpserver.o
+# Native Sources (compiled as usual)
+N_OBJ = main.o tap.o
+
+# Compilation Options
+CFLAGS := -Wall -std=gnu99 -g -Werror
+CPPFLAGS := -I include/ -I ../nativelib/include
+K_CPPFLAGS := -I $(KERNEL_SRC)include -I $(MODULE_SRC)
+LDFLAGS += -Wl,--defsym,__buildnum=$(BUILD_NUM) -g -L .. -lnativelib
+
+BUILDINFO_OBJ := obj/$(TARGET)/buildinfo.o
+BUILDINFO_SRC := $(BUILDINFO_OBJ:%.o=%.c)
+
+# ====================
+# == Start of Magic ==
+# ====================
+# -- Load modules ---
+$(foreach module,$(MODULES), $(eval include $(MODULE_SRC)$(module)/Makefile) $(eval M_OBJ += $(addprefix $(module)/,$(OBJ))) )
+
+# -- Apply Prefixes to object paths
+OBJ_PREFIX = obj/$(TARGET)/
+K_OBJ_PREFIX = $(OBJ_PREFIX)_Kernel/
+M_OBJ_PREFIX = $(OBJ_PREFIX)_Module/
+K_OBJ := $(addprefix $(K_OBJ_PREFIX),$(K_OBJ))
+M_OBJ := $(addprefix $(M_OBJ_PREFIX),$(M_OBJ))
+L_OBJ := $(addprefix $(OBJ_PREFIX),$(L_OBJ))
+N_OBJ := $(addprefix $(OBJ_PREFIX),$(N_OBJ))
+
+OBJ := $(N_OBJ) $(L_OBJ) $(K_OBJ) $(M_OBJ) $(BUILDINFO_OBJ)
+
+DEPFILES = $(filter %.o,$(OBJ))
+DEPFILES := $(DEPFILES:%=%.dep)
+
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+ $(RM) -f $(OBJ) $(DEPFILES) $(BIN)
+
+$(BIN): $(OBJ)
+ @echo [CC Link] -o $(BIN)
+ @$(CC) -o $(BIN) $(OBJ) $(LDFLAGS)
+ @echo BUILD_NUM = $$(( $(BUILD_NUM) + 1 )) > Makefile.BuildNum
+
+$(M_OBJ): $(M_OBJ_PREFIX)%.o: $(MODULE_SRC)%.c
+ @mkdir -p $(dir $@)
+ @echo [CC Module] -o $@
+ @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
+
+$(K_OBJ): $(K_OBJ_PREFIX)%.o: $(KERNEL_SRC)%.c
+ @mkdir -p $(dir $@)
+ @echo [CC Kernel] -o $@
+ @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
+
+$(L_OBJ): $(OBJ_PREFIX)%.o: %.c
+ @mkdir -p $(dir $@)
+ @echo [CC Local] -o $@
+ @$(CC) -c $< -o $@ -ffreestanding $(CFLAGS) $(CPPFLAGS) $(K_CPPFLAGS) -MMD -MP -MF
[email protected]
+
+$(N_OBJ): $(OBJ_PREFIX)%.o: %.c
+ @mkdir -p $(dir $@)
+ @echo [CC Native] -o $@
+
+# Hacky buildinfo.c file
+$(BUILDINFO_SRC): $(filter-out $(BUILDINFO_OBJ), $(OBJ)) Makefile
+ @echo "" > $@
+ @echo "const char gsKernelVersion[] = \"$(ACESS_VERSION)\";" >> $@
+ @echo "const char gsGitHash[] = \""`git log -n 1 | head -n 1 | awk '{print $$2}'`"\";" >> $@
+ @echo "const int giBuildNumber = $(BUILD_NUM);" >> $@
+ @echo "const char gsBuildInfo[] = \"Acess2 DiskTool v$(ACESS_VERSION)\";" >> $@
+$(BUILDINFO_OBJ): $(BUILDINFO_SRC)
+ @echo [CC] -o $@
+ @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
+
+$(OBJ): Makefile
+
+-include $(DEPFILES)
--- /dev/null
+/*
+ * Acess2 Networking Test Suite (NetTest)
+ * - By John Hodge (thePowersGang)
+ *
+ * nettest.h
+ * - Common functions
+ */
+#ifndef _NETTEST_H_
+#define _NETTEST_H_
+
+#include <stddef.h>
+
+extern int NativeNic_AddDev(char *Desc);
+
+extern void *NetTest_OpenTap(const char *Name);
+extern size_t NetTest_WritePacket(void *Handle, size_t Size, const void *Data);
+extern size_t NetTest_ReadPacket(void *Handle, size_t MaxSize, void *Data);
+
+#endif
+
--- /dev/null
+/*
+ *
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <acess_logging.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#define LOGHDR(col,type) fprintf(stderr, "\e["col"m[%-8.8s]"type" ", Ident)
+#define LOGTAIL() fprintf(stderr, "\e[0m\n")
+
+#define PUTERR(col,type) {\
+ LOGHDR(col,type);\
+ va_list args; va_start(args, Message);\
+ vfprintf(stderr, Message, args);\
+ va_end(args);\
+ LOGTAIL();\
+}
+
+// === CODE ===
+void Log_KernelPanic(const char *Ident, const char *Message, ...) {
+ PUTERR("35", "k")
+ abort();
+}
+void Log_Panic(const char *Ident, const char *Message, ...)
+ PUTERR("34", "p")
+void Log_Error(const char *Ident, const char *Message, ...)
+ PUTERR("31", "e")
+void Log_Warning(const char *Ident, const char *Message, ...)
+ PUTERR("33", "w")
+void Log_Notice(const char *Ident, const char *Message, ...)
+ PUTERR("32", "n")
+void Log_Log(const char *Ident, const char *Message, ...)
+ PUTERR("37", "l")
+void Log_Debug(const char *Ident, const char *Message, ...)
+ PUTERR("37", "d")
+
+void Warning(const char *Message, ...) {
+ const char *Ident = "";
+ PUTERR("33", "W")
+}
+void Log(const char *Message, ...) {
+ const char *Ident = "";
+ PUTERR("37", "L")
+}
+
+void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
+{
+ const uint8_t *data = Data;
+ size_t ofs;
+ fprintf(stderr, "[HexDump ]d %s: %i bytes\n", Prefix, (int)Length);
+ for( ofs = 0; ofs + 16 <= Length; ofs += 16 )
+ {
+ fprintf(stderr, "[HexDump ]d %s:", Prefix);
+ fprintf(stderr, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+ data += 8;
+ fprintf(stderr, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+ data += 8;
+ fprintf(stderr, "\n");
+ }
+
+ fprintf(stderr, "[HexDump ]d %s:", Prefix);
+ for( ; ofs < Length; ofs ++ )
+ {
+ if( ofs % 8 == 0 ) fprintf(stderr, " ");
+ fprintf(stderr, " %02x", data[ofs%16]);
+ }
+ fprintf(stderr, "\n");
+}
+
+ int giDebug_TraceLevel = 0;
+
+void Debug_TraceEnter(const char *Function, const char *Format, ...)
+{
+ const char *Ident = "Trace";
+ LOGHDR("37","T");
+ for( int i = 0; i < giDebug_TraceLevel; i ++ )
+ fprintf(stderr, " ");
+ fprintf(stderr, "%s: (", Function);
+
+ va_list args;
+ va_start(args, Format);
+
+ int hasBeenPrev = 0;
+ while(*Format)
+ {
+ while( *Format && isblank(*Format) )
+ Format ++;
+ if( !*Format ) break;
+
+ char type = *Format++;
+ const char *start = Format;
+ while( *Format && !isblank(*Format) )
+ Format ++;
+
+ if(hasBeenPrev)
+ fprintf(stderr, ",");
+ hasBeenPrev = 1;
+
+ fprintf(stderr, "%.*s=", (int)(Format-start), start);
+ switch(type)
+ {
+ case 'p':
+ fprintf(stderr, "%p", va_arg(args,const void *));
+ break;
+ case 's':
+ fprintf(stderr, "\"%s\"", va_arg(args,const char *));
+ break;
+ case 'i':
+ fprintf(stderr, "%i", va_arg(args,int));
+ break;
+ case 'x':
+ fprintf(stderr, "0x%x", va_arg(args,unsigned int));
+ break;
+ case 'X':
+ fprintf(stderr, "0x%"PRIx64, va_arg(args,uint64_t));
+ break;
+ default:
+ va_arg(args,uintptr_t);
+ fprintf(stderr, "?");
+ break;
+ }
+ }
+
+ va_end(args);
+
+ fprintf(stderr, ")");
+ LOGTAIL();
+ giDebug_TraceLevel ++;
+}
+
+void Debug_TraceLog(const char *Function, const char *Format, ...)
+{
+ const char *Ident = "Trace";
+ LOGHDR("37","T");
+
+ for( int i = 0; i < giDebug_TraceLevel; i ++ )
+ fprintf(stderr, " ");
+ fprintf(stderr, "%s: ", Function);
+
+ va_list args;
+ va_start(args, Format);
+
+ vfprintf(stderr, Format, args);
+
+ va_end(args);
+ LOGTAIL();
+}
+
+void Debug_TraceLeave(const char *Function, char Type, ...)
+{
+ if( giDebug_TraceLevel == 0 ) {
+ Log_Error("Debug", "Function %s called LEAVE without ENTER", Function);
+ }
+
+ const char *Ident = "Trace";
+ LOGHDR("37","T");
+
+ va_list args;
+ va_start(args, Type);
+
+ if( giDebug_TraceLevel > 0 )
+ {
+ giDebug_TraceLevel --;
+ for( int i = 0; i < giDebug_TraceLevel; i ++ )
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "%s: RETURN", Function);
+ switch(Type)
+ {
+ case '-':
+ break;
+ case 'i':
+ fprintf(stderr, " %i", va_arg(args, int));
+ break;
+ case 'x':
+ fprintf(stderr, " 0x%x", va_arg(args, unsigned int));
+ break;
+ case 'X':
+ fprintf(stderr, " 0x%"PRIx64, va_arg(args,uint64_t));
+ break;
+ case 's':
+ fprintf(stderr, " \"%s\"", va_arg(args, const char *));
+ break;
+ case 'p':
+ fprintf(stderr, " %p", va_arg(args, const void *));
+ break;
+ case 'n':
+ fprintf(stderr, " NULL");
+ break;
+ default:
+ fprintf(stderr, " ?");
+ break;
+ }
+
+ va_end(args);
+ LOGTAIL();
+}
+
--- /dev/null
+/*
+ * Acess2 Networking Test Suite (NetTest)
+ * - By John Hodge (thePowersGang)
+ *
+ * main.c
+ * - Program Core
+ */
+#include <stdio.h>
+#include <acess_logging.h>
+#include <nettest.h>
+#include <string.h>
+
+extern int IPStack_Install(char **Args);
+
+// === CODE ===
+void PrintUsage(const char *ProgramName)
+{
+ fprintf(stderr, "Usage: %s <commands...>\n", ProgramName);
+ fprintf(stderr, "\n");
+ fprintf(stderr,
+ "-dev <tapdev>:<mac>\n"
+ "-ip <dev>,<addr>,<mask>\n"
+ "-route <net>,<mask>,<nexthop>\n"
+ );
+}
+
+int main(int argc, char *argv[])
+{
+ if( argc <= 1 ) {
+ PrintUsage(argv[0]);
+ return 1;
+ }
+
+ // Startup
+ {
+ char *ipstack_args[] = {NULL};
+ IPStack_Install( ipstack_args );
+ }
+
+ for( int i = 0; i < argc; i ++ )
+ {
+ if( argv[i][0] != '-' ) {
+ }
+ else if( strcmp(argv[i], "-dev") == 0 )
+ {
+ if( ++i == argc ) { PrintUsage(argv[0]); return 1; }
+ NativeNic_AddDev(argv[i]);
+ }
+ }
+
+ // Run suite
+
+
+ // Teardown
+
+ return 0;
+}
--- /dev/null
+/*
+ * Acess2 Networking Test Suite (NetTest)
+ * - By John Hodge (thePowersGang)
+ *
+ * nic.c
+ * - Acess -> TAP Wrapper
+ */
+#include <acess.h>
+#include <IPStack/include/adapters_api.h>
+#include <nettest.h>
+
+// === CONSTANTS ===
+static const int MTU = 1520;
+
+// === PROTOTYPES ===
+void NativeNic_int_FreePacket(void *Ptr, size_t pkt_length, size_t Unused, const void *DataPtr);
+tIPStackBuffer *NativeNic_WaitForPacket(void *Ptr);
+ int NativeNic_SendPacket(void *Ptr, tIPStackBuffer *Buffer);
+
+// === GLOBALS ===
+tIPStack_AdapterType gNativeNIC_AdapterType = {
+ .Name = "NativeNIC",
+ .Type = 0, // TODO: Differentiate differnet wire protos and speeds
+ .Flags = 0, // TODO: IP checksum offloading, MAC checksum offloading etc
+ .SendPacket = NativeNic_SendPacket,
+ .WaitForPacket = NativeNic_WaitForPacket
+ };
+
+// === CODE ===
+int NativeNic_AddDev(char *DevDesc)
+{
+ Uint8 macaddr[6];
+ char *colonpos = strchr(DevDesc, ':');
+ if( !colonpos )
+ return -1;
+ *colonpos = 0;
+ if( UnHex(macaddr, 6, DevDesc) != 6 )
+ return -1;
+ void *ptr = NetTest_OpenTap(colonpos+1);
+ if( !ptr )
+ return 1;
+ IPStack_Adapter_Add(&gNativeNIC_AdapterType, ptr, macaddr);
+
+ return 0;
+}
+
+void NativeNic_int_FreePacket(void *Ptr, size_t pkt_length, size_t Unused, const void *DataPtr)
+{
+ free( (void*)DataPtr );
+}
+
+tIPStackBuffer *NativeNic_WaitForPacket(void *Ptr)
+{
+ char *buf = malloc( MTU );
+ size_t len;
+
+ len = NetTest_ReadPacket(Ptr, MTU, buf);
+
+ tIPStackBuffer *ret = IPStack_Buffer_CreateBuffer(1);
+ IPStack_Buffer_AppendSubBuffer(ret, len, 0, buf, NativeNic_int_FreePacket, Ptr);
+ return ret;
+}
+
+int NativeNic_SendPacket(void *Ptr, tIPStackBuffer *Buffer)
+{
+ size_t len = IPStack_Buffer_GetLength(Buffer);
+
+ // Check against MTU
+ if( len > MTU )
+ return -1;
+
+ // Serialise into stack
+ char buf[len];
+ IPStack_Buffer_GetData(Buffer, buf, len);
+
+ NetTest_WritePacket(Ptr, len, buf);
+ return 0;
+}
--- /dev/null
+/*
+ * Acess2 Networking Test Suite (NetTest)
+ * - By John Hodge (thePowersGang)
+ *
+ * tap.c
+ * - TAP Network driver
+ */
+#include <nettest.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+//#include <linux/if.h>
+#include <linux/if_tun.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+// === CODE ===
+void *NetTest_OpenTap(const char *Name)
+{
+ int rv;
+
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP|IFF_NO_PI;
+
+ if( Name[0] != '\0' )
+ {
+ if( strlen(Name) > IFNAMSIZ )
+ return NULL;
+ strncpy(ifr.ifr_name, Name, IFNAMSIZ);
+ }
+
+ int fd = open("/dev/net/tun", O_RDWR);
+ if( fd < 0 )
+ {
+ perror("NetTest_OpenTap - open");
+ return NULL;
+ }
+
+ if( (rv = ioctl(fd, TUNSETIFF, &ifr)) )
+ {
+ perror("NetTest_OpenTap - ioctl(TUNSETIFF)");
+ fprintf(stderr, "Opening TUN/TAP device '%s'\n", Name);
+ close(fd);
+ return NULL;
+ }
+
+ return (void*)(intptr_t)fd;
+}
+
+size_t NetTest_WritePacket(void *Handle, size_t Size, const void *Data)
+{
+ return write( (intptr_t)Handle, Data, Size);
+}
+
+size_t NetTest_ReadPacket(void *Handle, size_t MaxSize, void *Data)
+{
+ return read( (intptr_t)Handle, Data, MaxSize);
+}
--- /dev/null
+/*
+ * Acess2 Networking Test Suite (NetTest)
+ * - By John Hodge (thePowersGang)
+ *
+ * vfs_shim.c
+ * - VFS Layer Emulation
+ */
+#include <vfs.h>
+#include <vfs_int.h>
+#include <events.h>
+
+// === CODE ===
+int VFS_SelectNode(tVFS_Node *Node, int Type, tTime *Timeout, const char *Name)
+{
+
+ return 0;
+}
+
+int VFS_MarkAvaliable(tVFS_Node *Node, BOOL bAvail)
+{
+ Node->DataAvaliable = bAvail;
+ if( Node->DataAvaliable && Node->ReadThreads )
+ Threads_PostEvent( (void*)Node->ReadThreads, THREAD_EVENT_VFS );
+ return 0;
+}
+
+int VFS_MarkError(tVFS_Node *Node, BOOL bError)
+{
+ Node->ErrorOccurred = bError;
+ if( Node->ErrorOccurred && Node->ErrorThreads )
+ Threads_PostEvent( (void*)Node->ErrorThreads, THREAD_EVENT_VFS );
+ return 0;
+}
+
+int VFS_Open(const char *Path, Uint Flags)
+{
+ return -1;
+}
+
+void VFS_Close(int FD)
+{
+}
+
+tVFS_Handle *VFS_GetHandle(int FD)
+{
+ return NULL;
+}
+
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+
+// === PROTOTYPES ===
+ int main(int argc, char *argv[]);
+size_t RLE1_7(void *Dest, void *Src, size_t Size, int BlockSize, int BlockStep, int MinRunLength);
+uint32_t GetARGB(SDL_Surface *srf, int x, int y);
+
+// === CODE ===
+int main(int argc, char *argv[])
+{
+ FILE *fp;
+ SDL_Surface *img;
+ uint16_t word;
+ uint32_t val;
+ int y, x, i;
+ int rle32length, rle4x8length;
+ int bufLen;
+ uint32_t *buffer, *buffer2;
+
+ img = IMG_Load(argv[1]);
+ if( !img ) return -1;
+
+ buffer = malloc( img->w * img->h * 4 );
+
+ i = 0;
+ for( y = 0; y < img->h; y++ )
+ {
+ for( x = 0; x < img->w; x ++ )
+ {
+ val = GetARGB(img, x, y);
+ buffer[i++] = val;
+ }
+ }
+
+ SDL_FreeSurface(img);
+
+ // Try encoding using a single RLE stream
+ rle32length = RLE1_7(NULL, buffer, img->w * img->h, 4, 4, 3);
+
+ // Try encoding using separate RLE streams for each channel
+ rle4x8length = RLE1_7(NULL, buffer, img->w * img->h, 1, 4, 2);
+ rle4x8length += RLE1_7(NULL, ((uint8_t*)buffer)+1, img->w * img->h, 1, 4, 2);
+ rle4x8length += RLE1_7(NULL, ((uint8_t*)buffer)+2, img->w * img->h, 1, 4, 2);
+ rle4x8length += RLE1_7(NULL, ((uint8_t*)buffer)+3, img->w * img->h, 1, 4, 2);
+
+ printf("raw length = %i\n", img->w * img->h * 4);
+ printf("rle32length = %i\n", rle32length);
+ printf("rle4x8length = %i\n", rle4x8length);
+
+ if( rle32length < rle4x8length ) {
+ comp = 1; // 32-bit RLE
+ buffer2 = malloc( rle32length );
+ bufLen = RLE1_7(buffer2, buffer, img->w * img->h, 4, 4, 2);
+ }
+ else {
+ comp = 3; // 4x8 bit RLE
+ buffer2 = malloc( rle4x8length );
+ rle4x8length = RLE1_7(buffer2, buffer, img->w * img->h, 1, 4, 3);
+ rle4x8length += RLE1_7(buffer2+rle4x8length, ((uint8_t*)buffer)+1, img->w * img->h, 1, 4, 3);
+ rle4x8length += RLE1_7(buffer2+rle4x8length, ((uint8_t*)buffer)+2, img->w * img->h, 1, 4, 3);
+ rle4x8length += RLE1_7(buffer2+rle4x8length, ((uint8_t*)buffer)+3, img->w * img->h, 1, 4, 3);
+ bufLen = rle4x8length;
+ }
+
+ // Open and write
+ fp = fopen(argv[2], "w");
+ if( !fp ) return -1;
+
+ word = 0x51F0; fwrite(&word, 2, 1, fp);
+ word = comp&7; fwrite(&word, 2, 1, fp);
+ word = img->w; fwrite(&word, 2, 1, fp);
+ word = img->h; fwrite(&word, 2, 1, fp);
+
+ fwrite(buffer2, bufLen, 1, fp);
+
+ fclose(fp);
+
+ return 0;
+}
+
+#define USE_VERBATIM 1
+
+/**
+ * \brief Run Length Encode a data stream
+ * \param Dest Destination buffer (can be NULL)
+ * \param Src Source data
+ * \param Size Size of source data
+ * \param BlockSize Size of a data element (in bytes)
+ * \param BlockStep Separation of the beginning of each data element (must be > 0 and should be >= BlockSize)
+ * \param MinRunLength Minimum run length for RLE to be used (must be be >= 1)
+ *
+ * This function produces a RLE stream encoded with a 7-bit size and a
+ * verbatim flag (allowing strings of non-rle data to be included in the
+ * data for efficiency) of the data blocks from \a Src. Each block is
+ * \a BlockSize bytes in size.
+ *
+ * \a BlockStep allows this function to encode data that is interlaced with
+ * other data that you may not want to RLE together (for example, different
+ * colour channels in an image).
+ */
+size_t RLE1_7(void *Dest, void *Src, size_t Size, int BlockSize, int BlockStep, int MinRunLength)
+{
+ uint8_t *src = Src;
+ uint8_t *dest = Dest;
+ int ret = 0;
+ int i, j, k;
+ int nVerb = 0, nRLE = 0; // Debugging
+
+ //printf("RLE1_7: (Dest=%p, Src=%p, Size=%lu, BlockSize=%i, BlockStep=%i, MinRunLength=%i)\n",
+ // Dest, Src, Size, BlockSize, BlockStep, MinRunLength);
+
+ // Prevent errors
+ if( Size < BlockSize ) return -1;
+ if( !Src ) return -1;
+ if( BlockSize <= 0 || BlockStep <= 0 ) return -1;
+ if( MinRunLength < 1 ) return -1;
+
+ // Scan through the data stream
+ for( i = 0; i < Size; i ++ )
+ {
+ //printf("i = %i, ", i);
+ // Check forward for and get the "run length"
+ for( j = i + 1; j < i + 127 && j < Size; j ++ )
+ {
+ // Check for equality
+ for( k = 0; k < BlockSize; k ++ ) {
+ if( src[j*BlockStep+k] != src[i*BlockStep+k] ) break;
+ }
+ // If not, break
+ if( k < BlockSize ) break;
+ }
+
+ #if USE_VERBATIM
+ // Check for a verbatim range (runlength of `MinRunLength` or less)
+ if( j - i <= MinRunLength ) {
+ int nSame = 0;
+ // Get the length of the verbatim run
+ for( j = i + 1; j < i + 127 && j < Size; j ++ )
+ {
+ // Check for equality
+ for( k = 0; k < BlockSize; k ++ ) {
+ if( src[j*BlockStep+k] != src[i*BlockStep+k] ) break;
+ }
+ if( k == BlockSize ) {
+ nSame ++;
+ if( nSame > MinRunLength )
+ break;
+ }
+ else {
+ nSame = 0;
+ }
+ }
+
+ // Save data
+ if( dest ) {
+ dest[ret++] = (j - i) | 0x80; // Length (with high bit set)
+ // Data
+ for( k = 0; k < (j - i)*BlockSize; k ++ )
+ dest[ret++] = src[i*BlockStep+k];
+ }
+ else {
+ ret += 1 + BlockSize*(j - i);
+ }
+
+ nVerb ++;
+ }
+ // RLE Range
+ else {
+ #endif // USE_VERBATIM
+ // length = j - i (maxes out at 127)
+ if( dest ) {
+ dest[ret++] = j - i; // Length (with high bit unset)
+ for( k = 0; k < BlockSize; k ++ ) {
+ dest[ret++] = src[i*BlockStep+k];
+ }
+ }
+ else {
+ ret += 1 + BlockSize;
+ }
+
+ nRLE ++;
+ #if USE_VERBATIM
+ }
+ #endif
+
+ i = j;
+ }
+
+ //printf("nVerb = %i, nRLE = %i\n", nVerb, nRLE);
+ return ret;
+}
+
+uint32_t GetARGB(SDL_Surface *srf, int x, int y)
+{
+ uint8_t r, g, b, a;
+ SDL_GetRGBA(
+ *(uint32_t*)( srf->pixels + srf->format->BytesPerPixel*x + y * srf->pitch ),
+ srf->format, &r, &g, &b, &a
+ );
+ return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | ((uint32_t)b);
+}
--- /dev/null
+
+KERNEL_DIR := ../../KernelLand/Kernel
+
+NOBJ := logging.o misc.o
+KOBJ := threads.o time.o mutex.o
+
+NOBJ := $(NOBJ:%.o=obj/%.o)
+KOBJ := $(KOBJ:%.o=obj/%.o)
+OBJ := $(NOBJ) $(KOBJ)
+BIN := ../libnativelib.a
+
+CFLAGS := -Wall -std=c99 -Werror
+CPPFLAGS := -I include
+
+
+.PHONY: all clean
+
+all: $(BIN)
+
+clean:
+ $(RM) $(BIN) $(OBJ)
+
+$(BIN): $(OBJ)
+ ar cru $(BIN) $(OBJ)
+
+$(NOBJ): obj/%.o: %.c
+ @echo [CC Native] $@
+ @mkdir -p $(dir $@)
+ @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS)
+$(KOBJ): obj/%.o: %.c
+ @echo [CC Kernel] $@
+ @mkdir -p $(dir $@)
+ @$(CC) -o $@ -c $< $(CFLAGS) $(CPPFLAGS) -I $(KERNEL_DIR)/include
+
--- /dev/null
+/*
+ * Acess2 DiskTool utility
+ * - By John Hodge (thePowersGang)
+ *
+ * include/acess.h
+ * - Mock kernel core header
+ */
+#ifndef _DISKTOOL__ACESS_H_
+#define _DISKTOOL__ACESS_H_
+
+#define CONCAT(x,y) x ## y
+#define EXPAND_CONCAT(x,y) CONCAT(x,y)
+#define STR(x) #x
+#define EXPAND_STR(x) STR(x)
+
+#define ASSERT(x) do{}while(0)
+
+extern char __buildnum[];
+#define BUILD_NUM ((int)(Uint)&__buildnum)
+extern const char gsGitHash[];
+extern const char gsBuildInfo[];
+#define VER2(major,minor) ((((major)&0xFF)<<8)|((minor)&0xFF))
+
+
+#define BITS 32
+#define NULL ((void*)0)
+#include <stdint.h>
+
+typedef uintptr_t Uint;
+//typedef unsigned int size_t;
+#include <stddef.h>
+typedef uint64_t off_t;
+typedef char BOOL;
+
+
+typedef uint8_t Uint8;
+typedef uint16_t Uint16;
+typedef uint32_t Uint32;
+typedef uint64_t Uint64;
+
+typedef int8_t Sint8;
+typedef int16_t Sint16;
+typedef int32_t Sint32;
+typedef int64_t Sint64;
+
+typedef uintptr_t tVAddr;
+typedef uint32_t tPAddr;
+
+typedef uint32_t tUID;
+typedef uint32_t tGID;
+typedef uint32_t tTID;
+
+// NOTE: Since this is single-threaded (for now) mutexes can be implimented as simple locks
+typedef char tShortSpinlock;
+
+typedef int64_t tTime;
+extern tTime now(void);
+extern int64_t timestamp(int sec, int min, int hr, int day, int month, int year);
+extern void format_date(tTime TS, int *year, int *month, int *day, int *hrs, int *mins, int *sec, int *ms);
+
+#define PACKED __attribute__((packed))
+#define DEPRECATED
+#define EXPORT(s)
+#define EXPORTV(s)
+
+#include <vfs_ext.h>
+
+// These are actually library functions, but they can't be included, so they're defined manually
+extern void *malloc(size_t bytes);
+extern void *calloc(size_t nmemb, size_t size);
+extern void *realloc(void *oldptr, size_t bytes);
+extern void free(void *buffer);
+
+#include <errno.h>
+#include <acess_logging.h>
+
+// Threads
+extern int *Threads_GetErrno(void);
+//extern tPGID Threads_GetPGID(void);
+//extern tPID Threads_GetPID(void);
+extern tTID Threads_GetTID(void);
+extern tUID Threads_GetUID(void);
+extern tGID Threads_GetGID(void);
+
+extern struct sThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data);
+extern void Threads_Sleep(void);
+extern void Threads_Yield(void);
+extern int Threads_SetName(const char *NewName);
+
+// Kinda hacky way of not colliding with native errno
+#define errno (*(Threads_GetErrno()))
+
+/**
+ * \name Endianness Swapping
+ * \{
+ */
+#ifdef __BIG_ENDIAN__
+#define LittleEndian16(_val) SwapEndian16(_val)
+#define LittleEndian32(_val) SwapEndian32(_val)
+#define LittleEndian64(_val) SwapEndian32(_val)
+#define BigEndian16(_val) (_val)
+#define BigEndian32(_val) (_val)
+#define BigEndian64(_val) (_val)
+#else
+#define LittleEndian16(_val) (_val)
+#define LittleEndian32(_val) (_val)
+#define LittleEndian64(_val) (_val)
+#define BigEndian16(_val) SwapEndian16(_val)
+#define BigEndian32(_val) SwapEndian32(_val)
+#define BigEndian64(_val) SwapEndian64(_val)
+#endif
+extern Uint16 SwapEndian16(Uint16 Val);
+extern Uint32 SwapEndian32(Uint32 Val);
+extern Uint64 SwapEndian64(Uint64 Val);
+/**
+ * \}
+ */
+
+
+#include <string.h>
+#include <acess_string.h>
+#if 0
+extern int strucmp(const char *s1, const char *s2);
+extern int strpos(const char *Str, char Ch);
+extern void itoa(char *buf, uint64_t num, int base, int minLength, char pad);
+extern int snprintf(char *buf, size_t len, const char *fmt, ...);
+extern int sprintf(char *buf, const char *fmt, ...);
+extern int ReadUTF8(const Uint8 *str, Uint32 *Val);
+extern int WriteUTF8(Uint8 *str, Uint32 Val);
+extern int ParseInt(const char *string, int *Val);
+#include <ctype.h>
+extern int ModUtil_SetIdent(char *Dest, const char *Value);
+extern int ModUtil_LookupString(const char **Array, const char *Needle);
+extern Uint8 ByteSum(const void *Ptr, int Size);
+extern int Hex(char *Dest, size_t Size, const Uint8 *SourceData);
+extern int UnHex(Uint8 *Dest, size_t DestSize, const char *SourceString);
+#endif
+#define CheckString(str) (1)
+#define CheckMem(mem,sz) (1)
+extern int rand(void);
+
+// TODO: Move out?
+extern int DivUp(int value, int divisor);
+extern uint64_t DivMod64U(uint64_t Num, uint64_t Den, uint64_t *Rem);
+static inline int MIN(int a, int b) { return a < b ? a : b; }
+static inline int MAX(int a, int b) { return a > b ? a : b; }
+
+#if USE_MULTITHREADING
+#error "TODO: Impliment multithreaded SHORTLOCK"
+#else
+static inline void SHORTLOCK(tShortSpinlock *Lock) {
+ if(*Lock) Log_KernelPanic("---", "Double short lock");
+ *Lock = 1;
+}
+static inline void SHORTREL(tShortSpinlock *m) { *m = 0; }
+static inline int CPU_HAS_LOCK(tShortSpinlock *m) { return *m; }
+#endif
+
+static inline intptr_t MM_GetPhysAddr(void *Ptr) { return 1; }
+
+#endif
+
--- /dev/null
+
+#ifndef _DISKTOOL__ACESS_LOGGING_H_
+#define _DISKTOOL__ACESS_LOGGING_H_
+
+#if DEBUG
+# define ENTER(str, v...) Debug_TraceEnter(__func__, str, ##v)
+# define LOG(fmt, v...) Debug_TraceLog(__func__, fmt, ##v)
+# define LEAVE(t, v...) Debug_TraceLeave(__func__, t, ##v)
+# define LEAVE_RET(t,v) do{LEAVE('-');return v;}while(0)
+#else
+# define ENTER(...) do{}while(0)
+# define LOG(...) do{}while(0)
+# define LEAVE(...) do{}while(0)
+# define LEAVE_RET(t,v) do{return v;}while(0)
+#endif
+
+extern void Log_KernelPanic(const char *Ident, const char *Message, ...) __attribute__((noreturn));
+extern void Log_Panic(const char *Ident, const char *Message, ...);
+extern void Log_Error(const char *Ident, const char *Message, ...);
+extern void Log_Warning(const char *Ident, const char *Message, ...);
+extern void Log_Notice(const char *Ident, const char *Message, ...);
+extern void Log_Log(const char *Ident, const char *Message, ...);
+extern void Log_Debug(const char *Ident, const char *Message, ...);
+
+extern void Warning(const char *Message, ...);
+extern void Log(const char *Message, ...);
+extern void Debug_HexDump(const char *Prefix, const void *Data, size_t Length);
+
+extern void Debug_TraceEnter(const char *Function, const char *Format, ...);
+extern void Debug_TraceLog(const char *Function, const char *Format, ...);
+extern void Debug_TraceLeave(const char *Function, char Type, ...);
+
+#endif
+
--- /dev/null
+/*
+ *
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <acess_logging.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#define LOGHDR(col,type) fprintf(stderr, "\e["col"m[%-8.8s]"type" ", Ident)
+#define LOGTAIL() fprintf(stderr, "\e[0m\n")
+
+#define PUTERR(col,type) {\
+ LOGHDR(col,type);\
+ va_list args; va_start(args, Message);\
+ vfprintf(stderr, Message, args);\
+ va_end(args);\
+ LOGTAIL();\
+}
+
+// === CODE ===
+void Log_KernelPanic(const char *Ident, const char *Message, ...) {
+ PUTERR("35", "k")
+ abort();
+}
+void Log_Panic(const char *Ident, const char *Message, ...)
+ PUTERR("34", "p")
+void Log_Error(const char *Ident, const char *Message, ...)
+ PUTERR("31", "e")
+void Log_Warning(const char *Ident, const char *Message, ...)
+ PUTERR("33", "w")
+void Log_Notice(const char *Ident, const char *Message, ...)
+ PUTERR("32", "n")
+void Log_Log(const char *Ident, const char *Message, ...)
+ PUTERR("37", "l")
+void Log_Debug(const char *Ident, const char *Message, ...)
+ PUTERR("37", "d")
+
+void Warning(const char *Message, ...) {
+ const char *Ident = "";
+ PUTERR("33", "W")
+}
+void Log(const char *Message, ...) {
+ const char *Ident = "";
+ PUTERR("37", "L")
+}
+
+void Debug_HexDump(const char *Prefix, const void *Data, size_t Length)
+{
+ const uint8_t *data = Data;
+ size_t ofs;
+ fprintf(stderr, "[HexDump ]d %s: %i bytes\n", Prefix, (int)Length);
+ for( ofs = 0; ofs + 16 <= Length; ofs += 16 )
+ {
+ fprintf(stderr, "[HexDump ]d %s:", Prefix);
+ fprintf(stderr, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+ data += 8;
+ fprintf(stderr, " %02x %02x %02x %02x %02x %02x %02x %02x",
+ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
+ data += 8;
+ fprintf(stderr, "\n");
+ }
+
+ fprintf(stderr, "[HexDump ]d %s:", Prefix);
+ for( ; ofs < Length; ofs ++ )
+ {
+ if( ofs % 8 == 0 ) fprintf(stderr, " ");
+ fprintf(stderr, " %02x", data[ofs%16]);
+ }
+ fprintf(stderr, "\n");
+}
+
+ int giDebug_TraceLevel = 0;
+
+void Debug_TraceEnter(const char *Function, const char *Format, ...)
+{
+ const char *Ident = "Trace";
+ LOGHDR("37","T");
+ for( int i = 0; i < giDebug_TraceLevel; i ++ )
+ fprintf(stderr, " ");
+ fprintf(stderr, "%s: (", Function);
+
+ va_list args;
+ va_start(args, Format);
+
+ int hasBeenPrev = 0;
+ while(*Format)
+ {
+ while( *Format && isblank(*Format) )
+ Format ++;
+ if( !*Format ) break;
+
+ char type = *Format++;
+ const char *start = Format;
+ while( *Format && !isblank(*Format) )
+ Format ++;
+
+ if(hasBeenPrev)
+ fprintf(stderr, ",");
+ hasBeenPrev = 1;
+
+ fprintf(stderr, "%.*s=", (int)(Format-start), start);
+ switch(type)
+ {
+ case 'p':
+ fprintf(stderr, "%p", va_arg(args,const void *));
+ break;
+ case 's':
+ fprintf(stderr, "\"%s\"", va_arg(args,const char *));
+ break;
+ case 'i':
+ fprintf(stderr, "%i", va_arg(args,int));
+ break;
+ case 'x':
+ fprintf(stderr, "0x%x", va_arg(args,unsigned int));
+ break;
+ case 'X':
+ fprintf(stderr, "0x%"PRIx64, va_arg(args,uint64_t));
+ break;
+ default:
+ va_arg(args,uintptr_t);
+ fprintf(stderr, "?");
+ break;
+ }
+ }
+
+ va_end(args);
+
+ fprintf(stderr, ")");
+ LOGTAIL();
+ giDebug_TraceLevel ++;
+}
+
+void Debug_TraceLog(const char *Function, const char *Format, ...)
+{
+ const char *Ident = "Trace";
+ LOGHDR("37","T");
+
+ for( int i = 0; i < giDebug_TraceLevel; i ++ )
+ fprintf(stderr, " ");
+ fprintf(stderr, "%s: ", Function);
+
+ va_list args;
+ va_start(args, Format);
+
+ vfprintf(stderr, Format, args);
+
+ va_end(args);
+ LOGTAIL();
+}
+
+void Debug_TraceLeave(const char *Function, char Type, ...)
+{
+ if( giDebug_TraceLevel == 0 ) {
+ Log_Error("Debug", "Function %s called LEAVE without ENTER", Function);
+ }
+
+ const char *Ident = "Trace";
+ LOGHDR("37","T");
+
+ va_list args;
+ va_start(args, Type);
+
+ if( giDebug_TraceLevel > 0 )
+ {
+ giDebug_TraceLevel --;
+ for( int i = 0; i < giDebug_TraceLevel; i ++ )
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "%s: RETURN", Function);
+ switch(Type)
+ {
+ case '-':
+ break;
+ case 'i':
+ fprintf(stderr, " %i", va_arg(args, int));
+ break;
+ case 'x':
+ fprintf(stderr, " 0x%x", va_arg(args, unsigned int));
+ break;
+ case 'X':
+ fprintf(stderr, " 0x%"PRIx64, va_arg(args,uint64_t));
+ break;
+ case 's':
+ fprintf(stderr, " \"%s\"", va_arg(args, const char *));
+ break;
+ case 'p':
+ fprintf(stderr, " %p", va_arg(args, const void *));
+ break;
+ case 'n':
+ fprintf(stderr, " NULL");
+ break;
+ default:
+ fprintf(stderr, " ?");
+ break;
+ }
+
+ va_end(args);
+ LOGTAIL();
+}
+
--- /dev/null
+/*
+ * Acess2 nativelib
+ * - By John Hodge (thePowersGang)
+ *
+ * misc.c
+ * - Random functions
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h> // strcasecmp
+
+// TODO: Move into a helper lib?
+void itoa(char *buf, uint64_t num, int base, int minLength, char pad)
+{
+ char fmt[] = "%0ll*x";
+ switch(base)
+ {
+ case 8: fmt[5] = 'o'; break;
+ case 10: fmt[5] = 'd'; break;
+ case 16: fmt[5] = 'x'; break;
+ }
+ if(pad != '0') {
+ fmt[1] = '%';
+ sprintf(buf, fmt+1, minLength, num);
+ }
+ else {
+ sprintf(buf, fmt, minLength, num);
+ }
+}
+
+int ParseInt(const char *string, int *value)
+{
+ char *next;
+ *value = strtol(string, &next, 0);
+ return next - string;
+}
+
+int strpos(const char *Str, char Ch)
+{
+ const char *r = strchr(Str, Ch);
+ if(!r) return -1;
+ return r - Str;
+}
+
+int strucmp(const char *s1, const char *s2)
+{
+ return strcasecmp(s1, s2);
+}
+
+uint64_t DivMod64U(uint64_t value, uint64_t divisor, uint64_t *remainder)
+{
+ if(remainder)
+ *remainder = value % divisor;
+ return value / divisor;
+}
--- /dev/null
+/*
+ * Acess2 libnative (Kernel Simulation Library)
+ * - By John Hodge (thePowersGang)
+ *
+ * mutex.c
+ * - Mutex emulation
+ */
+#include <mutex.h>
+
+
+// === CODE ===
+int Mutex_Acquire(tMutex *Mutex)
+{
+ // TODO: Assert
+ return 0;
+}
+
+void Mutex_Release(tMutex *Mutex)
+{
+ return;
+}
+
--- /dev/null
+/*
+ * Acess2 libnative (Kernel Simulation Library)
+ * - By John Hodge (thePowersGang)
+ *
+ * threads.c
+ * - Threads handling
+ */
+#include <acess.h>
+#include <threads.h>
+
+// === CODE ===
+tThread *Proc_GetCurThread(void)
+{
+ return NULL;
+}
+
+void Threads_PostEvent(tThread *Thread, Uint32 Events)
+{
+
+}
+
+Uint32 Threads_WaitEvents(Uint32 Events)
+{
+ Log_KernelPanic("Threads", "Can't use _WaitEvents in DiskTool");
+ return 0;
+}
+
+void Threads_ClearEvent(Uint32 Mask)
+{
+
+}
+
+tUID Threads_GetUID(void) { return 0; }
+tGID Threads_GetGID(void) { return 0; }
+
+tTID Threads_GetTID(void) { return 0; }
+
+int *Threads_GetMaxFD(void) { static int max_fd=32; return &max_fd; }
+char **Threads_GetCWD(void) { static char *cwd; return &cwd; }
+char **Threads_GetChroot(void) { static char *chroot; return &chroot; }
+
+void Threads_Yield(void)
+{
+ Log_Warning("Threads", "Threads_Yield DEFINITELY shouldn't be used");
+}
+
+void Threads_Sleep(void)
+{
+ Log_Warning("Threads", "Threads_Sleep shouldn't be used");
+}
+
+int Threads_SetName(const char *Name)
+{
+ Log_Notice("Threads", "TODO: Threads_SetName('%s')", Name);
+ return 0;
+}
+
+int *Threads_GetErrno(void) __attribute__ ((weak));
+
+int *Threads_GetErrno(void)// __attribute__ ((weak))
+{
+ static int a_errno;
+ return &a_errno;
+}
+
+struct sThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
+{
+ Log_Error("Threads", "TODO - Use pthreads to impliment Proc_SpawnWorker");
+ return NULL;
+}
+
--- /dev/null
+/*
+ * Acess2 DiskTool
+ * - By John Hodge (thePowersGang)
+ *
+ * time.c
+ * - Timing functions (emulated)
+ */
+#include <acess.h>
+#include <timers.h>
+
+// === CODE ===
+tTimer *Time_AllocateTimer(tTimerCallback *Callback, void *Argument)
+{
+ return NULL;
+}
+
+void Time_ScheduleTimer(tTimer *Timer, int Delta)
+{
+
+}
+
+void Time_RemoveTimer(tTimer *Timer)
+{
+
+}
+
+void Time_FreeTimer(tTimer *Timer)
+{
+
+}
+
+Sint64 now(void)
+{
+ // TODO: Translate UNIX time into Acess time
+ return 0;
+}
+
// TODO: This shouldn't really be done, instead focus should be given
// when the menu is shown.
// WM_FocusWindow(Window);
+ WM_RaiseWindow(Window); // If it's shown, raise it to the heavens!
}
else
{