├── filesysbox.library_rev.rev ├── dismount ├── FbxDismount_rev.rev ├── FbxDismount_rev.h ├── makefile └── dismount.c ├── icons ├── def_doc.info ├── def_drawer.info └── def_install.info ├── Install-AROS ├── .gitignore ├── filesysbox.library_rev.h ├── mkheaders.sh ├── src ├── fschangefileposition.c ├── fschangefilesize.c ├── fscurrentvolume.c ├── allocvecpooled.c ├── fsinhibit.c ├── fsgetfileposition.c ├── fsunlock.c ├── codesets.h ├── fsduplock.c ├── fsgetfilesize.c ├── fsremovenotify.c ├── fschangemode.c ├── fssamelock.c ├── debugf.c ├── fuse_stubs.h ├── fswriteprotect.c ├── fsread.c ├── main │ ├── FbxVersion.c │ ├── FbxCopyStringBSTRToC.c │ ├── FbxFuseVersion.c │ ├── FbxCopyStringCToBSTR.c │ ├── FbxGetUpTime.c │ ├── FbxSignalDiskChange.c │ ├── FbxGetSysTime.c │ ├── FbxReturnMountMsg.c │ ├── FbxUninstallTimerCallback.c │ ├── FbxSetSignalCallback.c │ ├── FbxInstallTimerCallback.c │ ├── FbxQueryMountMsg.c │ ├── FbxCleanupFS.c │ └── FbxQueryFS.c ├── fsformat.c ├── fsseek.c ├── fswrite.c ├── fsrelabel.c ├── dopacket64.c ├── fsparentdir.c ├── fsexamineallend.c ├── fsclose.c ├── fsopenfromlock.c ├── xattrs.c ├── fsdie.c ├── fssetownerinfo.c ├── fscreatesoftlink.c ├── fslock.c ├── filesysbox_vectors.c ├── fscreatehardlink.c ├── fssetcomment.c ├── fuse_stubs.c ├── fsreadlink.c ├── fscreatedir.c ├── fssetprotection.c ├── fsinfodata.c ├── strlcpy.c ├── fsdelete.c ├── fssetfilesize.c ├── fssetdate.c ├── timer.c ├── fsaddnotify.c ├── diskchange.c ├── avl.c ├── notify.c ├── fsexaminelock.c ├── fsexaminenext.c ├── fsrename.c ├── init.c ├── filesysbox_vectors.h ├── volume.c ├── doslist.c ├── fsopen.c └── dofmt.c ├── README ├── Install ├── include ├── fd │ └── filesysbox_lib.fd ├── proto │ └── filesysbox.h ├── sys │ └── statvfs.h ├── clib │ └── filesysbox_protos.h ├── inline │ └── filesysbox.h ├── defines │ └── filesysbox.h └── pragmas │ └── filesysbox_pragmas.h ├── filesysbox_lib.sfd ├── mkrelease.sh ├── makefile └── releasenotes /filesysbox.library_rev.rev: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /dismount/FbxDismount_rev.rev: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /icons/def_doc.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salass00/filesysbox/HEAD/icons/def_doc.info -------------------------------------------------------------------------------- /icons/def_drawer.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salass00/filesysbox/HEAD/icons/def_drawer.info -------------------------------------------------------------------------------- /icons/def_install.info: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salass00/filesysbox/HEAD/icons/def_install.info -------------------------------------------------------------------------------- /Install-AROS: -------------------------------------------------------------------------------- 1 | (welcome) 2 | (set @default-dest "LIBS:") 3 | (copylib 4 | (prompt "Copying filesysbox.library") 5 | (help @copylib-help) 6 | (source "Libs/filesysbox.library") 7 | (dest @default-dest) 8 | ) 9 | (exit) 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore object, dependency and archive files 2 | *.[oda] 3 | # Ignore generated exe files 4 | bin 5 | obj 6 | # Ignore generated autodoc file 7 | filesysbox.doc 8 | # Ignore release archives 9 | *.7z 10 | *.iso 11 | *.lha 12 | -------------------------------------------------------------------------------- /dismount/FbxDismount_rev.h: -------------------------------------------------------------------------------- 1 | #define VERSION 54 2 | #define REVISION 1 3 | #define DATE "28.6.2023" 4 | #define VERS "FbxDismount 54.1" 5 | #define VSTRING "FbxDismount 54.1 (28.6.2023)\r\n" 6 | #define VERSTAG "\0$VER: FbxDismount 54.1 (28.6.2023)" 7 | -------------------------------------------------------------------------------- /filesysbox.library_rev.h: -------------------------------------------------------------------------------- 1 | #define VERSION 54 2 | #define REVISION 7 3 | #define DATE "10.6.2025" 4 | #define VERS "filesysbox.library 54.7" 5 | #define VSTRING "filesysbox.library 54.7 (10.6.2025)\r\n" 6 | #define VERSTAG "\0$VER: filesysbox.library 54.7 (10.6.2025)" 7 | -------------------------------------------------------------------------------- /mkheaders.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Script for generating the SDK headers. 4 | # 5 | 6 | sfdc --mode=clib -o include/clib/filesysbox_protos.h filesysbox_lib.sfd 7 | sfdc --mode=fd -o include/fd/filesysbox_lib.fd filesysbox_lib.sfd 8 | sfdc --mode=pragmas -o include/pragmas/filesysbox_pragmas.h filesysbox_lib.sfd 9 | sfdc --mode=macros --target=i386-pc-aros -o include/defines/filesysbox.h filesysbox_lib.sfd 10 | sfdc --mode=macros --target=m68k-amigaos -o include/inline/filesysbox.h filesysbox_lib.sfd 11 | sfdc --mode=proto -o include/proto/filesysbox.h filesysbox_lib.sfd 12 | -------------------------------------------------------------------------------- /src/fschangefileposition.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #ifdef ENABLE_DP64_SUPPORT 12 | #include "filesysbox_internal.h" 13 | 14 | int FbxChangeFilePosition(struct FbxFS *fs, struct FbxLock *lock, QUAD pos, int mode) { 15 | if (FbxSeekFile64(fs, lock, pos, mode) == -1) { 16 | return DOSFALSE; 17 | } 18 | 19 | return DOSTRUE; 20 | } 21 | 22 | #endif /* #ifdef ENABLE_DP64_SUPPORT */ 23 | 24 | -------------------------------------------------------------------------------- /src/fschangefilesize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #ifdef ENABLE_DP64_SUPPORT 12 | #include "filesysbox_internal.h" 13 | 14 | int FbxChangeFileSize(struct FbxFS *fs, struct FbxLock *lock, QUAD offs, int mode) { 15 | if (FbxSetFileSize64(fs, lock, offs, mode) == -1) { 16 | return DOSFALSE; 17 | } 18 | 19 | return DOSTRUE; 20 | } 21 | 22 | #endif /* #ifdef ENABLE_DP64_SUPPORT */ 23 | 24 | -------------------------------------------------------------------------------- /src/fscurrentvolume.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | BPTR FbxCurrentVolume(struct FbxFS *fs, struct FbxLock *lock) { 14 | fs->r2 = fs->fssm ? fs->fssm->fssm_Unit : -1; // yeah.. 15 | if (lock != NULL) { 16 | CHECKLOCK(lock, ZERO); 17 | return lock->volumebptr; 18 | } else { 19 | CHECKVOLUME(ZERO); 20 | return MKBADDR(fs->currvol); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Filesysbox.library is a FUSE compatible file system layer originally developed 2 | by Leif Salomonsson. It manages locks, notifications, file handles, packets, 3 | update timeouts and more, freeing the file system of these jobs. Version 0.730 4 | of the library was released as open source and was used as a basis for this 5 | version. 6 | 7 | Installation: 8 | 9 | Copy Libs/filesysbox.library LIBS: 10 | 11 | Source code: 12 | 13 | The source code for current and older versions is available under APL license 14 | on github: 15 | 16 | https://github.com/salass00/filesysbox 17 | 18 | Changes: 19 | 20 | For a list of changes in this and earlier versions see the releasenotes file. 21 | 22 | -------------------------------------------------------------------------------- /Install: -------------------------------------------------------------------------------- 1 | (welcome) 2 | (set @default-dest "LIBS:") 3 | (if (patmatch "(68000|68010)" (database "cpu")) 4 | (set cpu_ver 0) 5 | (if (patmatch "68060" (database "cpu")) 6 | (set cpu_ver 2) 7 | (set cpu_ver 1) 8 | ) 9 | ) 10 | (set cpu_ver (askchoice 11 | (prompt "Which CPU version to install?") 12 | (help @askchoice-help) 13 | (choices "68000" "68020+" "68060") 14 | (default cpu_ver) 15 | )) 16 | (set libname 17 | ("Libs/filesysbox.library.%s" 18 | (select cpu_ver "000" "020" "060") 19 | ) 20 | ) 21 | (copylib 22 | (prompt "Copying filesysbox.library") 23 | (help @copylib-help) 24 | (source libname) 25 | (dest @default-dest) 26 | (newname "filesysbox.library") 27 | ) 28 | (exit) 29 | 30 | -------------------------------------------------------------------------------- /src/allocvecpooled.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #include "filesysbox_internal.h" 9 | 10 | #ifndef __AROS__ 11 | extern struct Library *SysBase; 12 | 13 | APTR AllocVecPooled(APTR mempool, ULONG size) { 14 | ULONG *pmem; 15 | 16 | pmem = AllocPooled(mempool, sizeof(ULONG) + size); 17 | if (pmem != NULL) 18 | *pmem++ = size; 19 | 20 | return pmem; 21 | } 22 | 23 | void FreeVecPooled(APTR mempool, APTR ptr) { 24 | ULONG *pmem; 25 | ULONG size; 26 | 27 | if (ptr != NULL) { 28 | pmem = ptr; 29 | size = *--pmem; 30 | FreePooled(mempool, pmem, sizeof(ULONG) + size); 31 | } 32 | } 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /src/fsinhibit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxInhibit(struct FbxFS *fs, int inhibit) { 14 | PDEBUGF("FbxInhibit(%#p, %d)\n", fs, inhibit); 15 | 16 | if (inhibit) { 17 | if (fs->inhibit == 0) { 18 | FbxCleanupVolume(fs); 19 | } 20 | fs->inhibit++; 21 | } else { 22 | if (fs->inhibit) { 23 | fs->inhibit--; 24 | if (fs->inhibit == 0) { 25 | fs->dosetup = TRUE; 26 | } 27 | } 28 | } 29 | 30 | return DOSTRUE; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /include/fd/filesysbox_lib.fd: -------------------------------------------------------------------------------- 1 | * "filesysbox.library" 2 | * Automatically generated FD (sfdc 1.12)! Do not edit! 3 | ##base _FileSysBoxBase 4 | ##bias 30 5 | ##public 6 | * "filesysbox.library" 7 | FbxQueryMountMsg(msg,attr)(a0,d0) 8 | FbxSetupFS(msg,tags,ops,opssize,udata)(a0,a1,a2,d0,a3) 9 | FbxEventLoop(fs)(a0) 10 | FbxCleanupFS(fs)(a0) 11 | FbxReturnMountMsg(msg,r1,r2)(a0,d0,d1) 12 | FbxFuseVersion()() 13 | FbxVersion()() 14 | FbxSetSignalCallback(fs,func,signals)(a0,a1,d0) 15 | FbxInstallTimerCallback(fs,func,period)(a0,a1,d0) 16 | FbxUninstallTimerCallback(fs,cb)(a0,a1) 17 | FbxSignalDiskChange(fs)(a0) 18 | FbxCopyStringBSTRToC(src,dst,size)(a0,a1,d0) 19 | FbxCopyStringCToBSTR(src,dst,size)(a0,a1,d0) 20 | FbxQueryFS(fs,tags)(a0,a1) 21 | FbxGetSysTime(fs,tv)(a0,a1) 22 | FbxGetUpTime(fs,tv)(a0,a1) 23 | ##end 24 | -------------------------------------------------------------------------------- /src/fsgetfileposition.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | QUAD FbxGetFilePosition(struct FbxFS *fs, struct FbxLock *lock) { 14 | PDEBUGF("FbxGetFilePosition(%#p, %#p)\n", fs, lock); 15 | 16 | CHECKVOLUME(-1); 17 | 18 | CHECKLOCK(lock, -1); 19 | 20 | if (lock->fsvol != fs->currvol) { 21 | fs->r2 = ERROR_NO_DISK; 22 | return -1; 23 | } 24 | 25 | if (lock->info->nonseekable) { 26 | fs->r2 = ERROR_ACTION_NOT_KNOWN; 27 | return -1; 28 | } 29 | 30 | fs->r2 = 0; 31 | return lock->filepos; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /src/fsunlock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxUnLockObject(struct FbxFS *fs, struct FbxLock *lock) { 14 | struct FbxEntry *e; 15 | 16 | PDEBUGF("FbxUnLockObject(%#p, %#p)\n", fs, lock); 17 | 18 | if (lock == NULL) { 19 | debugf("FbxUnLockObject got a NULL lock, btw.\n"); 20 | fs->r2 = 0; 21 | return DOSTRUE; 22 | } 23 | 24 | CHECKLOCK(lock, DOSFALSE); 25 | 26 | e = lock->entry; 27 | 28 | FbxEndLock(fs, lock); 29 | FbxCleanupEntry(fs, e); 30 | 31 | fs->r2 = 0; 32 | return DOSTRUE; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /src/codesets.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #ifndef CODESETS_H 12 | #define CODESETS_H 1 13 | 14 | #include 15 | 16 | struct FbxCodeSet 17 | { 18 | void (*gen_maptab)(FbxUCS *maptab); 19 | }; 20 | 21 | struct FbxFS; /* Forward declaration */ 22 | 23 | const struct FbxCodeSet *FbxFindCodeSetByName(struct FbxFS *fs, CONST_STRPTR name); 24 | const struct FbxCodeSet *FbxFindCodeSetByCountry(struct FbxFS *fs, ULONG country); 25 | const struct FbxCodeSet *FbxFindCodeSetByLanguage(struct FbxFS *fs, CONST_STRPTR language); 26 | 27 | #endif /* CODESETS_H */ 28 | 29 | -------------------------------------------------------------------------------- /src/fsduplock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | struct FbxLock *FbxDupLock(struct FbxFS *fs, struct FbxLock *lock) { 14 | PDEBUGF("FbxDupLock(%#x)\n", lock); 15 | 16 | CHECKVOLUME(NULL); 17 | 18 | if (lock != NULL) { 19 | CHECKLOCK(lock, NULL); 20 | 21 | if (lock->fsvol != fs->currvol) { 22 | fs->r2 = ERROR_NO_DISK; 23 | return NULL; 24 | } 25 | 26 | lock = FbxLockEntry(fs, lock->entry, SHARED_LOCK); 27 | if (lock == NULL) return NULL; 28 | } else { 29 | lock = FbxLocateObject(fs, NULL, "", SHARED_LOCK); 30 | if (lock == NULL) return NULL; 31 | } 32 | 33 | fs->r2 = 0; 34 | return lock; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /include/proto/filesysbox.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated header (sfdc 1.12)! Do not edit! */ 2 | 3 | #ifndef PROTO_FILESYSBOX_H 4 | #define PROTO_FILESYSBOX_H 5 | 6 | #include 7 | 8 | #ifndef _NO_INLINE 9 | # if defined(__GNUC__) 10 | # ifdef __AROS__ 11 | # include 12 | # else 13 | # include 14 | # endif 15 | # else 16 | # include 17 | # endif 18 | #endif /* _NO_INLINE */ 19 | 20 | #ifdef __amigaos4__ 21 | # include 22 | # ifndef __NOGLOBALIFACE__ 23 | extern struct FileSysBoxIFace *IFileSysBox; 24 | # endif /* __NOGLOBALIFACE__*/ 25 | #endif /* !__amigaos4__ */ 26 | #ifndef __NOLIBBASE__ 27 | extern struct Library * 28 | # ifdef __CONSTLIBBASEDECL__ 29 | __CONSTLIBBASEDECL__ 30 | # endif /* __CONSTLIBBASEDECL__ */ 31 | FileSysBoxBase; 32 | #endif /* !__NOLIBBASE__ */ 33 | 34 | #endif /* !PROTO_FILESYSBOX_H */ 35 | -------------------------------------------------------------------------------- /src/fsgetfilesize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | 14 | QUAD FbxGetFileSize(struct FbxFS *fs, struct FbxLock *lock) { 15 | struct fbx_stat statbuf; 16 | int error; 17 | 18 | PDEBUGF("FbxGetFileSize(%#p, %#p)\n", fs, lock); 19 | 20 | CHECKVOLUME(-1); 21 | 22 | CHECKLOCK(lock, -1); 23 | 24 | if (lock->fsvol != fs->currvol) { 25 | fs->r2 = ERROR_NO_DISK; 26 | return -1; 27 | } 28 | 29 | error = Fbx_fgetattr(fs, lock->entry->path, &statbuf, lock->info); 30 | if (error) { 31 | fs->r2 = FbxFuseErrno2Error(error); 32 | return -1; 33 | } 34 | 35 | fs->r2 = 0; 36 | return statbuf.st_size; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /include/sys/statvfs.h: -------------------------------------------------------------------------------- 1 | #ifndef _SYS_STATVFS_H 2 | #define _SYS_STATVFS_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #if !defined(__AROS__) && !defined(_FSBLKCNT_T_DECLARED) 9 | typedef unsigned long fsblkcnt_t; 10 | typedef unsigned long fsfilcnt_t; 11 | #endif 12 | 13 | struct statvfs 14 | { 15 | unsigned long f_bsize; 16 | unsigned long f_frsize; 17 | fsblkcnt_t f_blocks; 18 | fsblkcnt_t f_bfree; 19 | fsblkcnt_t f_bavail; 20 | 21 | fsfilcnt_t f_files; 22 | fsfilcnt_t f_ffree; 23 | fsfilcnt_t f_favail; 24 | 25 | unsigned long f_fsid; 26 | unsigned long f_flag; 27 | unsigned long f_namemax; 28 | }; 29 | 30 | #define ST_RDONLY 0x0001 /* Read-only file system. */ 31 | #define ST_NOSUID 0x0002 /* Does not support the semantics of the ST_ISUID and ST_ISGID file mode bits. */ 32 | #define ST_CASE_SENSITIVE 0x0004 /* The file system is case sensitive. */ 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif /* _SYS_STATVFS_H */ 39 | -------------------------------------------------------------------------------- /src/fsremovenotify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxRemoveNotify(struct FbxFS *fs, struct NotifyRequest *nr) { 14 | struct Library *SysBase = fs->sysbase; 15 | struct FbxNotifyNode *nn; 16 | 17 | PDEBUGF("action_rem_notify(%#p, %#p)\n", fs, nr); 18 | 19 | if (nr->nr_Handler != fs->fsport) { 20 | fs->r2 = 0; 21 | return DOSFALSE; 22 | } 23 | 24 | nn = (struct FbxNotifyNode *)nr->nr_notifynode; 25 | 26 | Remove((struct Node *)&nn->chain); 27 | Remove((struct Node *)&nn->volumechain); 28 | 29 | if (nn->entry != NULL) { 30 | FbxCleanupEntry(fs, nn->entry); 31 | } 32 | 33 | FreeFbxNotifyNode(nn); 34 | 35 | nr->nr_MsgCount = 0; 36 | nr->nr_notifynode = (IPTR)NULL; 37 | return DOSTRUE; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/fschangemode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxChangeMode(struct FbxFS *fs, struct FbxLock *lock, int mode) { 14 | PDEBUGF("FbxChangeMode(%#p, %#p, %d)\n", fs, lock, mode); 15 | 16 | CHECKVOLUME(DOSFALSE); 17 | 18 | CHECKLOCK(lock, DOSFALSE); 19 | 20 | if (lock->fsvol != fs->currvol) { 21 | fs->r2 = ERROR_NO_DISK; 22 | return DOSFALSE; 23 | } 24 | 25 | if (!OneInMinList(&lock->entry->locklist)) { 26 | fs->r2 = ERROR_OBJECT_IN_USE; 27 | return DOSFALSE; 28 | } 29 | 30 | lock->access = mode; 31 | if (mode == EXCLUSIVE_LOCK) { 32 | lock->entry->xlock = TRUE; 33 | } else if (mode == SHARED_LOCK) { 34 | lock->entry->xlock = FALSE; 35 | } else { 36 | fs->r2 = ERROR_BAD_NUMBER; 37 | return DOSFALSE; 38 | } 39 | 40 | fs->r2 = 0; 41 | return DOSTRUE; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/fssamelock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxSameLock(struct FbxFS *fs, struct FbxLock *lock, struct FbxLock *lock2) { 14 | PDEBUGF("FbxSameLock(%#p, %#p, %#p)\n", fs, lock, lock2); 15 | 16 | CHECKVOLUME(DOSFALSE); 17 | 18 | CHECKLOCK(lock, DOSFALSE); 19 | CHECKLOCK(lock2, DOSFALSE); 20 | 21 | fs->r2 = 0; 22 | if (lock == lock2) return DOSTRUE; 23 | if (lock->fsvol == lock2->fsvol) { 24 | struct FbxEntry *entry = lock->entry; 25 | struct FbxEntry *entry2 = lock2->entry; 26 | 27 | /* Check for same entries */ 28 | if (entry == entry2) 29 | return DOSTRUE; 30 | 31 | /* Compare inodes (if valid) */ 32 | if (fs->fsflags & FBXF_USE_INO) 33 | { 34 | if (entry->diskkey != 0 && entry->diskkey == entry2->diskkey) 35 | return DOSTRUE; 36 | } 37 | } 38 | return DOSFALSE; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/debugf.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #ifndef NODEBUG 9 | #include "filesysbox_internal.h" 10 | //#include 11 | 12 | extern struct Library *SysBase; 13 | 14 | int debug_putc_cb(char ch, void *udata) { 15 | #ifdef __AROS__ 16 | //char tmp[4]; 17 | //tmp[0] = ch; 18 | //tmp[1] = '\0'; 19 | //KPutStr((CONST_STRPTR)tmp); 20 | struct Library *SysBase = udata; 21 | RawPutChar(ch); 22 | #else 23 | //KPutChar((unsigned char)ch); 24 | register char _d0 __asm__("d0") = ch; 25 | register struct Library *_a6 __asm__("a6") = udata; 26 | __asm__("jsr -516(a6)" 27 | : 28 | : "d" (_d0), "a" (_a6) 29 | : "d0", "d1", "a0", "a1", "cc" 30 | ); 31 | #endif 32 | return 0; 33 | } 34 | 35 | int vdebugf(const char *fmt, va_list args) { 36 | return FbxDoFmt(debug_putc_cb, SysBase, fmt, args); 37 | } 38 | 39 | int debugf(const char *fmt, ...) { 40 | va_list ap; 41 | va_start(ap, fmt); 42 | int retval = vdebugf(fmt, ap); 43 | va_end(ap); 44 | return retval; 45 | } 46 | #endif /* !NODEBUG */ 47 | 48 | -------------------------------------------------------------------------------- /src/fuse_stubs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #ifndef FUSE_STUBS_H 12 | #define FUSE_STUBS_H 1 13 | 14 | int Fbx_getattr(struct FbxFS *fs, const char *path, struct fbx_stat *stat); 15 | int Fbx_statfs(struct FbxFS *fs, const char *name, struct statvfs *stat); 16 | int Fbx_release(struct FbxFS *fs, const char *path, struct fuse_file_info *fi); 17 | int Fbx_fsync(struct FbxFS *fs, const char *path, int x, struct fuse_file_info *fi); 18 | int Fbx_fgetattr(struct FbxFS *fs, const char *path, struct fbx_stat *stat, 19 | struct fuse_file_info *fi); 20 | int Fbx_setxattr(struct FbxFS *fs, const char *path, const char *attr, 21 | CONST_APTR buf, size_t len, int flags); 22 | int Fbx_getxattr(struct FbxFS *fs, const char *path, const char *attr, 23 | APTR buf, size_t len); 24 | int Fbx_removexattr(struct FbxFS *fs, const char *path, const char *attr); 25 | 26 | #endif /* FUSE_STUBS_H */ 27 | 28 | -------------------------------------------------------------------------------- /src/fswriteprotect.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxWriteProtect(struct FbxFS *fs, int on_off, IPTR passkey) { 14 | PDEBUGF("FbxWriteProtect(%#p, %d, %#p)\n", fs, on_off, (APTR)passkey); 15 | 16 | CHECKVOLUME(DOSFALSE); 17 | 18 | if (on_off) { // protect? 19 | if (fs->currvol->writeprotect) { 20 | if (fs->currvol->passkey == 0 && passkey == 0) { 21 | fs->r2 = 0; 22 | return DOSTRUE; 23 | } else { 24 | fs->r2 = ERROR_WRITE_PROTECTED; 25 | return DOSFALSE; 26 | } 27 | } else { 28 | fs->currvol->writeprotect = TRUE; 29 | fs->currvol->passkey = passkey; 30 | FbxFlushAll(fs); 31 | } 32 | } else { // unprotect 33 | if (fs->currvol->writeprotect) { 34 | if (fs->currvol->passkey != 0 && fs->currvol->passkey != passkey) { 35 | fs->r2 = ERROR_BAD_NUMBER; 36 | return DOSFALSE; 37 | } 38 | fs->currvol->writeprotect = FALSE; 39 | } 40 | } 41 | fs->r2 = 0; 42 | return DOSTRUE; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /src/fsread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_read(struct FbxFS *fs, const char *path, char *buf, size_t len, 14 | QUAD offset, struct fuse_file_info *fi) 15 | { 16 | ODEBUGF("Fbx_read(%#p, '%s', %#p, %lu, %lld, %#p)\n", fs, path, buf, len, offset, fi); 17 | 18 | return FSOP read(path, buf, len, offset, fi, &fs->fcntx); 19 | } 20 | 21 | int FbxReadFile(struct FbxFS *fs, struct FbxLock *lock, APTR buffer, int bytes) { 22 | int res; 23 | 24 | PDEBUGF("FbxReadFile(%#p, %#p, %#p, %d)\n", fs, lock, buffer, bytes); 25 | 26 | CHECKVOLUME(-1); 27 | 28 | CHECKLOCK(lock, -1); 29 | 30 | if (lock->fsvol != fs->currvol) { 31 | fs->r2 = ERROR_NO_DISK; 32 | return -1; 33 | } 34 | 35 | if (bytes == 0) { 36 | fs->r2 = 0; 37 | return 0; 38 | } 39 | 40 | res = Fbx_read(fs, lock->entry->path, buffer, bytes, lock->filepos, lock->info); 41 | if (res < 0) { 42 | fs->r2 = FbxFuseErrno2Error(res); 43 | return -1; 44 | } 45 | 46 | lock->filepos += res; 47 | fs->r2 = 0; 48 | return res; 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/main/FbxVersion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxVersion *************************************** 16 | * 17 | * NAME 18 | * FbxVersion -- Get Filesysbox version. 19 | * 20 | * SYNOPSIS 21 | * LONG FbxVersion(void); 22 | * 23 | * FUNCTION 24 | * 25 | * INPUTS 26 | * 27 | * RESULT 28 | * Version number. 29 | * 30 | * EXAMPLE 31 | * 32 | * NOTES 33 | * 34 | * BUGS 35 | * 36 | * SEE ALSO 37 | * FbxFuseVersion() 38 | * 39 | ***************************************************************************** 40 | * 41 | */ 42 | 43 | #ifdef __AROS__ 44 | AROS_LH0(LONG, FbxVersion, 45 | struct FileSysBoxBase *, libBase, 11, FileSysBox) 46 | { 47 | AROS_LIBFUNC_INIT 48 | #else 49 | LONG FbxVersion( 50 | REG(a6, struct FileSysBoxBase *libBase)) 51 | { 52 | #endif 53 | ADEBUGF("FbxVersion()\n"); 54 | 55 | return FILESYSBOX_VERSION; 56 | 57 | #ifdef __AROS__ 58 | AROS_LIBFUNC_EXIT 59 | #endif 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/main/FbxCopyStringBSTRToC.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | #include 15 | 16 | void CopyStringBSTRToC(BSTR bstr, char *cstr, size_t size) { 17 | #if defined(__AROS__) && defined(AROS_FAST_BSTR) 18 | strlcpy(cstr, (const char *)bstr, size); 19 | #else 20 | UBYTE *src = BADDR(bstr); 21 | size_t len = *src++; 22 | if (len >= size) len = size-1; 23 | memcpy(cstr, src, len); 24 | cstr[len] = '\0'; 25 | #endif 26 | } 27 | 28 | #ifdef __AROS__ 29 | AROS_LH3(void, FbxCopyStringBSTRToC, 30 | AROS_LHA(BSTR, src, A0), 31 | AROS_LHA(STRPTR, dst, A1), 32 | AROS_LHA(ULONG, size, D0), 33 | struct FileSysBoxBase *, libBase, 16, FileSysBox) 34 | { 35 | AROS_LIBFUNC_INIT 36 | #else 37 | void FbxCopyStringBSTRToC( 38 | REG(a0, BSTR src), 39 | REG(a1, STRPTR dst), 40 | REG(d0, ULONG size), 41 | REG(a6, struct FileSysBoxBase *libBase)) 42 | { 43 | #endif 44 | 45 | CopyStringBSTRToC(src, (char *)dst, size); 46 | 47 | #ifdef __AROS__ 48 | AROS_LIBFUNC_EXIT 49 | #endif 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/main/FbxFuseVersion.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxFuseVersion *********************************** 16 | * 17 | * NAME 18 | * FbxFuseVersion -- Get FUSE API version. 19 | * 20 | * SYNOPSIS 21 | * LONG FbxFuseVersion(void); 22 | * 23 | * FUNCTION 24 | * 25 | * INPUTS 26 | * 27 | * RESULT 28 | * FUSE API version number. 29 | * 30 | * EXAMPLE 31 | * 32 | * NOTES 33 | * 34 | * BUGS 35 | * 36 | * SEE ALSO 37 | * FbxVersion() 38 | * 39 | ***************************************************************************** 40 | * 41 | */ 42 | 43 | #ifdef __AROS__ 44 | AROS_LH0(LONG, FbxFuseVersion, 45 | struct FileSysBoxBase *, libBase, 10, FileSysBox) 46 | { 47 | AROS_LIBFUNC_INIT 48 | #else 49 | LONG FbxFuseVersion( 50 | REG(a6, struct FileSysBoxBase *libBase)) 51 | { 52 | #endif 53 | ADEBUGF("FbxFuseVersion()\n"); 54 | 55 | return FUSE_VERSION; 56 | 57 | #ifdef __AROS__ 58 | AROS_LIBFUNC_EXIT 59 | #endif 60 | } 61 | 62 | -------------------------------------------------------------------------------- /src/fsformat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_format(struct FbxFS *fs, const char *volname, ULONG dostype) 14 | { 15 | ODEBUGF("Fbx_format(%#p, '%s', %#lx)\n", fs, volname, dostype); 16 | 17 | return FSOP format(volname, dostype, &fs->fcntx); 18 | } 19 | 20 | int FbxFormat(struct FbxFS *fs, const char *volname, ULONG dostype) { 21 | int error; 22 | #ifdef ENABLE_CHARSET_CONVERSION 23 | char fsvolname[FBX_MAX_NAME]; 24 | #endif 25 | 26 | PDEBUGF("FbxFormat(%#p, '%s', %#lx)\n", fs, volname, dostype); 27 | 28 | if (!fs->inhibit) { 29 | fs->r2 = ERROR_OBJECT_IN_USE; 30 | return DOSFALSE; 31 | } 32 | 33 | #ifdef ENABLE_CHARSET_CONVERSION 34 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 35 | if (FbxLocalToUTF8(fs, fsvolname, volname, FBX_MAX_NAME) >= FBX_MAX_NAME) { 36 | fs->r2 = ERROR_LINE_TOO_LONG; 37 | return DOSFALSE; 38 | } 39 | volname = fsvolname; 40 | } 41 | #else 42 | CHECKSTRING(volname, DOSFALSE); 43 | #endif 44 | 45 | error = Fbx_format(fs, volname, dostype); 46 | if (error) { 47 | fs->r2 = FbxFuseErrno2Error(error); 48 | return DOSFALSE; 49 | } 50 | 51 | fs->r2 = 0; 52 | return DOSTRUE; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/fsseek.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | QUAD FbxSeekFile64(struct FbxFS *fs, struct FbxLock *lock, QUAD pos, int mode) { 14 | QUAD newpos, oldpos, size; 15 | 16 | PDEBUGF("FbxSeekFile(%#p, %#p, %lld, %d)\n", fs, lock, pos, mode); 17 | 18 | oldpos = FbxGetFilePosition(fs, lock); 19 | if (oldpos == -1) return -1; 20 | 21 | size = FbxGetFileSize(fs, lock); 22 | if (size == -1) return -1; 23 | 24 | switch (mode) { 25 | case OFFSET_BEGINNING: 26 | newpos = pos; 27 | break; 28 | case OFFSET_CURRENT: 29 | newpos = oldpos + pos; 30 | break; 31 | case OFFSET_END: 32 | newpos = size + pos; 33 | break; 34 | default: 35 | fs->r2 = ERROR_SEEK_ERROR; 36 | return -1; 37 | } 38 | 39 | if (newpos < 0 || newpos > size) { 40 | fs->r2 = ERROR_SEEK_ERROR; 41 | return -1; 42 | } 43 | 44 | lock->filepos = newpos; 45 | fs->r2 = 0; 46 | return oldpos; 47 | } 48 | 49 | SIPTR FbxSeekFile(struct FbxFS *fs, struct FbxLock *lock, SIPTR pos, int mode) { 50 | QUAD oldpos; 51 | 52 | oldpos = FbxSeekFile64(fs, lock, pos, mode); 53 | if (oldpos != (SIPTR)oldpos) { 54 | fs->r2 = ERROR_OBJECT_TOO_LARGE; 55 | return -1; 56 | } 57 | 58 | return (SIPTR)oldpos; 59 | } 60 | 61 | -------------------------------------------------------------------------------- /src/fswrite.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_write(struct FbxFS *fs, const char *path, const char *buf, size_t len, 14 | QUAD offset, struct fuse_file_info *fi) 15 | { 16 | ODEBUGF("Fbx_write(%#p, '%s', %#p, %lu, %lld, %#p)\n", fs, path, buf, len, offset, fi); 17 | 18 | return FSOP write(path, buf, len, offset, fi, &fs->fcntx); 19 | } 20 | 21 | int FbxWriteFile(struct FbxFS *fs, struct FbxLock *lock, CONST_APTR buffer, int bytes) { 22 | int res; 23 | 24 | PDEBUGF("FbxWriteFile(%#p, %#p, %#p, %d)\n", fs, lock, buffer, bytes); 25 | 26 | CHECKVOLUME(-1); 27 | CHECKWRITABLE(-1); 28 | 29 | CHECKLOCK(lock, -1); 30 | 31 | if (lock->fsvol != fs->currvol) { 32 | fs->r2 = ERROR_NO_DISK; 33 | return -1; 34 | } 35 | 36 | if (bytes == 0) { 37 | fs->r2 = 0; 38 | return 0; 39 | } 40 | 41 | res = Fbx_write(fs, lock->entry->path, buffer, bytes, lock->filepos, lock->info); 42 | if (res < 0) { 43 | fs->r2 = FbxFuseErrno2Error(res); 44 | return -1; 45 | } 46 | 47 | if (res > 0) { 48 | lock->filepos += bytes; 49 | lock->flags |= LOCKFLAG_MODIFIED; // for notification 50 | FbxSetModifyState(fs, 1); 51 | } 52 | 53 | fs->r2 = (res == bytes) ? 0 : -1; 54 | return res; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/fsrelabel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include 13 | 14 | static int Fbx_relabel(struct FbxFS *fs, const char *volname) 15 | { 16 | ODEBUGF("Fbx_relabel(%#p, '%s')\n", fs, volname); 17 | 18 | return FSOP relabel(volname, &fs->fcntx); 19 | } 20 | 21 | int FbxRelabel(struct FbxFS *fs, const char *volname) { 22 | struct FbxVolume *vol = fs->currvol; 23 | int error; 24 | #ifdef ENABLE_CHARSET_CONVERSION 25 | char fsvolname[FBX_MAX_NAME]; 26 | #endif 27 | const char *advolname = volname; 28 | 29 | PDEBUGF("FbxRelabel(%#p, '%s')\n", fs, volname); 30 | 31 | CHECKVOLUME(DOSFALSE); 32 | CHECKWRITABLE(DOSFALSE); 33 | 34 | #ifdef ENABLE_CHARSET_CONVERSION 35 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 36 | if (FbxLocalToUTF8(fs, fsvolname, volname, FBX_MAX_NAME) >= FBX_MAX_NAME) { 37 | fs->r2 = ERROR_LINE_TOO_LONG; 38 | return DOSFALSE; 39 | } 40 | volname = fsvolname; 41 | } 42 | #else 43 | CHECKSTRING(volname, DOSFALSE); 44 | #endif 45 | 46 | error = Fbx_relabel(fs, volname); 47 | if (error) { 48 | fs->r2 = FbxFuseErrno2Error(error); 49 | return DOSFALSE; 50 | } 51 | 52 | FbxAsyncRenameVolume(fs, vol, advolname); 53 | 54 | FbxNotifyDiskChange(fs, IECLASS_DISKINSERTED); 55 | 56 | fs->r2 = 0; 57 | return DOSTRUE; 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/dopacket64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #ifdef ENABLE_DP64_SUPPORT 12 | #include "filesysbox_internal.h" 13 | 14 | QUAD FbxDoPacket64(struct FbxFS *fs, struct DosPacket64 *pkt) { 15 | LONG type; 16 | QUAD r1; 17 | 18 | PDEBUGF("FbxDoPacket64(%#p, %#p)\n", fs, pkt); 19 | 20 | #ifndef NODEBUG 21 | struct Task *callertask = pkt->dp_Port->mp_SigTask; 22 | PDEBUGF("action %ld task %#p '%s'\n", pkt->dp_Type, callertask, callertask->tc_Node.ln_Name); 23 | #endif 24 | 25 | type = pkt->dp_Type; 26 | switch (type) { 27 | case ACTION_CHANGE_FILE_POSITION64: 28 | r1 = FbxChangeFilePosition(fs, (struct FbxLock *)BADDR(pkt->dp_Arg1), pkt->dp_Arg2, pkt->dp_Arg3); 29 | break; 30 | case ACTION_GET_FILE_POSITION64: 31 | r1 = FbxGetFilePosition(fs, (struct FbxLock *)BADDR(pkt->dp_Arg1)); 32 | break; 33 | case ACTION_CHANGE_FILE_SIZE64: 34 | r1 = FbxChangeFileSize(fs, (struct FbxLock *)BADDR(pkt->dp_Arg1), pkt->dp_Arg2, pkt->dp_Arg3); 35 | break; 36 | case ACTION_GET_FILE_SIZE64: 37 | r1 = FbxGetFileSize(fs, (struct FbxLock *)BADDR(pkt->dp_Arg1)); 38 | break; 39 | default: 40 | r1 = DOSFALSE; 41 | fs->r2 = ERROR_ACTION_NOT_KNOWN; 42 | break; 43 | } 44 | 45 | PDEBUGF("Done with packet %#p. r1 %lld r2 %#p\n\n", pkt, r1, (APTR)fs->r2); 46 | 47 | return r1; 48 | } 49 | 50 | #endif /* ENABLE_DP64_SUPPORT */ 51 | 52 | -------------------------------------------------------------------------------- /src/main/FbxCopyStringCToBSTR.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | #include 15 | 16 | #ifndef __AROS__ 17 | static size_t strnlen(const char *str, size_t maxlen) 18 | { 19 | const char *s = str; 20 | 21 | while (maxlen && *s++ != '\0') maxlen--; 22 | 23 | return (s - str); 24 | } 25 | #endif 26 | 27 | void CopyStringCToBSTR(const char *cstr, BSTR bstr, size_t size) { 28 | #if defined(__AROS__) && defined(AROS_FAST_BSTR) 29 | strlcpy((char *)bstr, cstr, size); 30 | #else 31 | UBYTE *dst = BADDR(bstr); 32 | size_t len = strnlen(cstr, 255); 33 | if (len >= size) len = size-1; 34 | *dst++ = len; 35 | memcpy(dst, cstr, len); 36 | #endif 37 | } 38 | 39 | #ifdef __AROS__ 40 | AROS_LH3(void, FbxCopyStringCToBSTR, 41 | AROS_LHA(CONST_STRPTR, src, A0), 42 | AROS_LHA(BSTR, dst, A1), 43 | AROS_LHA(ULONG, size, D0), 44 | struct FileSysBoxBase *, libBase, 17, FileSysBox) 45 | { 46 | AROS_LIBFUNC_INIT 47 | #else 48 | void FbxCopyStringCToBSTR( 49 | REG(a0, CONST_STRPTR src), 50 | REG(a1, BSTR dst), 51 | REG(d0, ULONG size), 52 | REG(a6, struct FileSysBoxBase *libBase)) 53 | { 54 | #endif 55 | 56 | CopyStringCToBSTR((const char *)src, dst, size); 57 | 58 | #ifdef __AROS__ 59 | AROS_LIBFUNC_EXIT 60 | #endif 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/fsparentdir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include 13 | 14 | BOOL FbxParentPath(struct FbxFS *fs, char *pathbuf) { 15 | if (IsRoot(pathbuf)) { 16 | // can't parent root 17 | return FALSE; 18 | } 19 | char *p = strrchr(pathbuf, '/'); 20 | if (p != NULL) { 21 | if (p == pathbuf) p++; // leave the root '/' alone 22 | *p = '\0'; 23 | return TRUE; 24 | } 25 | // should never happen 26 | return FALSE; 27 | } 28 | 29 | struct FbxLock *FbxLocateParent(struct FbxFS *fs, struct FbxLock *lock) { 30 | char pname[FBX_MAX_PATH]; 31 | const char *name; 32 | 33 | PDEBUGF("FbxLocateParent(%#p, %#p)\n", fs, lock); 34 | 35 | CHECKVOLUME(NULL); 36 | 37 | if (lock == NULL) { 38 | fs->r2 = 0; // yes 39 | return NULL; 40 | } 41 | 42 | CHECKLOCK(lock, NULL); 43 | 44 | if (lock->fsvol != fs->currvol) { 45 | fs->r2 = ERROR_NO_DISK; 46 | return NULL; 47 | } 48 | 49 | FbxStrlcpy(fs, pname, lock->entry->path, FBX_MAX_PATH); 50 | if (!FbxParentPath(fs, pname)) { 51 | // can't parent root 52 | fs->r2 = 0; // yes 53 | return NULL; 54 | } 55 | 56 | name = pname; 57 | if (*name == '/') name++; // skip preceding slash character 58 | lock = FbxLocateObject(fs, NULL, name, SHARED_LOCK); 59 | if (lock == NULL) return NULL; 60 | 61 | fs->r2 = 0; 62 | return lock; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /filesysbox_lib.sfd: -------------------------------------------------------------------------------- 1 | ==id $Id$ 2 | * "filesysbox.library" 3 | ==base _FileSysBoxBase 4 | ==basetype struct Library * 5 | ==libname filesysbox.library 6 | ==bias 30 7 | ==public 8 | ==include 9 | ==include 10 | ==include 11 | ==include 12 | ==include 13 | APTR FbxQueryMountMsg(struct Message * msg, LONG attr) (a0,d0) 14 | struct FbxFS * FbxSetupFS(struct Message * msg, const struct TagItem * tags, const struct fuse_operations * ops, LONG opssize, APTR udata) (a0,a1,a2,d0,a3) 15 | LONG FbxEventLoop(struct FbxFS * fs) (a0) 16 | void FbxCleanupFS(struct FbxFS * fs) (a0) 17 | void FbxReturnMountMsg(struct Message * msg, SIPTR r1, SIPTR r2) (a0,d0,d1) 18 | LONG FbxFuseVersion() () 19 | LONG FbxVersion() () 20 | void FbxSetSignalCallback(struct FbxFS * fs, FbxSignalCallbackFunc func, ULONG signals) (a0,a1,d0) 21 | struct FbxTimerCallbackData * FbxInstallTimerCallback(struct FbxFS * fs, FbxTimerCallbackFunc func, ULONG period) (a0,a1,d0) 22 | void FbxUninstallTimerCallback(struct FbxFS * fs, struct FbxTimerCallbackData * cb) (a0,a1) 23 | void FbxSignalDiskChange(struct FbxFS * fs) (a0) 24 | void FbxCopyStringBSTRToC(BSTR src, STRPTR dst, ULONG size) (a0,a1,d0) 25 | void FbxCopyStringCToBSTR(CONST_STRPTR src, BSTR dst, ULONG size) (a0,a1,d0) 26 | void FbxQueryFS(struct FbxFS * fs, const struct TagItem * tags) (a0,a1) 27 | ==varargs 28 | void FbxQueryFSTags(struct FbxFS * fs, Tag tags, ...) (a0,a1) 29 | void FbxGetSysTime(struct FbxFS * fs, struct timeval * tv) (a0,a1) 30 | void FbxGetUpTime(struct FbxFS * fs, struct timeval * tv) (a0,a1) 31 | ==end 32 | 33 | -------------------------------------------------------------------------------- /dismount/makefile: -------------------------------------------------------------------------------- 1 | HOST ?= i386-aros 2 | 3 | CC = $(HOST)-gcc 4 | STRIP = $(HOST)-strip 5 | 6 | TARGET = FbxDismount 7 | VERSION = 54 8 | 9 | INCLUDES = -I. 10 | DEFINES = -D__NOLIBBASE__ 11 | WARNINGS = -Werror -Wall -Wwrite-strings -Wno-attributes 12 | 13 | CFLAGS = -O2 -g -fomit-frame-pointer $(INCLUDES) $(DEFINES) $(WARNINGS) 14 | LDFLAGS = -nostartfiles 15 | 16 | ifneq (,$(SYSROOT)) 17 | CFLAGS := --sysroot=$(SYSROOT) $(CFLAGS) 18 | LDFLAGS := --sysroot=$(SYSROOT) $(LDFLAGS) 19 | endif 20 | 21 | ifneq (,$(findstring -aros,$(HOST))) 22 | CPU = $(patsubst %-aros,%,$(HOST)) 23 | endif 24 | 25 | ifeq ($(HOST),m68k-amigaos) 26 | ARCH = -mcpu=68000 -mtune=68020-60 27 | CFLAGS := $(ARCH) -noixemul -fno-common $(CFLAGS) 28 | LDFLAGS := $(ARCH) -noixemul $(LDFLAGS) 29 | endif 30 | 31 | SRCS = dismount.c 32 | 33 | ifeq ($(HOST),m68k-amigaos) 34 | OBJS = $(addprefix obj/,$(SRCS:.c=.o)) 35 | else 36 | OBJS = $(addprefix obj/$(CPU)/,$(SRCS:.c=.o)) 37 | endif 38 | 39 | .PHONY: all 40 | 41 | ifeq ($(HOST),m68k-amigaos) 42 | all: bin/$(TARGET) 43 | 44 | obj/%.o: %.c 45 | @mkdir -p $(dir $@) 46 | $(CC) $(CFLAGS) -c -o $@ $< 47 | 48 | bin/$(TARGET): $(OBJS) 49 | @mkdir -p $(dir $@) 50 | $(CC) $(LDFLAGS) -o $@.debug $^ 51 | $(STRIP) $(STRIPFLAGS) -o $@ $@.debug 52 | else 53 | all: bin/$(TARGET).$(CPU) bin/$(TARGET).$(CPU).debug 54 | 55 | obj/$(CPU)/%.o: %.c 56 | @mkdir -p $(dir $@) 57 | $(CC) $(CFLAGS) -c -o $@ $< 58 | 59 | bin/$(TARGET).$(CPU).debug: $(OBJS) 60 | @mkdir -p $(dir $@) 61 | $(CC) $(LDFLAGS) -o $@ $^ 62 | 63 | bin/$(TARGET).$(CPU): $(OBJS) 64 | @mkdir -p $(dir $@) 65 | $(CC) -s $(LDFLAGS) -o $@ $^ 66 | endif 67 | 68 | .PHONY: clean 69 | clean: 70 | rm -rf bin obj 71 | 72 | .PHONY: revision 73 | revision: 74 | bumprev -e si $(VERSION) $(TARGET) 75 | 76 | -------------------------------------------------------------------------------- /src/fsexamineallend.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | extern struct Library *SysBase; 14 | 15 | void FreeFbxDirData(struct FbxLock *lock, struct FbxDirData *dd) { 16 | if (dd != NULL) { 17 | APTR pool = lock->mempool; 18 | 19 | if (dd->name != NULL) 20 | FreeVecPooled(pool, dd->name); 21 | 22 | if (dd->comment != NULL) 23 | FreeVecPooled(pool, dd->comment); 24 | 25 | FreeVecPooled(pool, dd); 26 | } 27 | } 28 | 29 | void FreeFbxDirDataList(struct FbxLock *lock, struct MinList *list) { 30 | struct MinNode *chain, *succ; 31 | 32 | for (chain = list->mlh_Head; (succ = chain->mln_Succ) != NULL; chain = succ) { 33 | FreeFbxDirData(lock, FSDIRDATAFROMNODE(chain)); 34 | } 35 | 36 | NEWMINLIST(list); 37 | } 38 | 39 | int FbxExamineAllEnd(struct FbxFS *fs, struct FbxLock *lock, APTR buffer, SIPTR len, 40 | int type, struct ExAllControl *ctrl) 41 | { 42 | struct Library *SysBase = fs->sysbase; 43 | struct FbxExAllState *exallstate; 44 | 45 | PDEBUGF("FbxExamineAllEnd(%#p, %#p, %#p, %d, %d, %#p)\n", fs, lock, buffer, len, type, ctrl); 46 | 47 | if (ctrl != NULL) { 48 | exallstate = (struct FbxExAllState *)ctrl->eac_LastKey; 49 | if (exallstate) { 50 | if (exallstate != (APTR)-1) { 51 | FreeFbxDirDataList(lock, &exallstate->freelist); 52 | FreeFbxExAllState(lock, exallstate); 53 | } 54 | ctrl->eac_LastKey = (IPTR)NULL; 55 | } 56 | } 57 | 58 | if (lock != NULL) FreeFbxDirDataList(lock, &lock->dirdatalist); 59 | 60 | fs->r2 = 0; 61 | return DOSTRUE; 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/main/FbxGetUpTime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxGetUpTime ****************************************** 16 | * 17 | * NAME 18 | * FbxGetUpTime -- Get the current up time. (V54.5) 19 | * 20 | * SYNOPSIS 21 | * void FbxGetUpTime(struct FbxFS *fs, struct timeval *tv); 22 | * 23 | * FUNCTION 24 | * Reads the current up time and stores it in the supplied 25 | * timeval structure. Basically just a convenient way to call 26 | * GetUpTime() from a filesysbox handler that doesn't require 27 | * the "timer.device" to be opened again. 28 | * 29 | * INPUTS 30 | * fs - The result of FbxSetupFS(). 31 | * tv - TimeVal structure to store the time in. 32 | * 33 | * RESULT 34 | * This function does not return a result 35 | * 36 | * EXAMPLE 37 | * 38 | * NOTES 39 | * 40 | * BUGS 41 | * 42 | * SEE ALSO 43 | * 44 | ***************************************************************************** 45 | * 46 | */ 47 | 48 | #ifdef __AROS__ 49 | AROS_LH2(void, FbxGetUpTime, 50 | AROS_LHA(struct FbxFS *, fs, A0), 51 | AROS_LHA(struct timeval *, tv, A1), 52 | struct FileSysBoxBase *, libBase, 20, FileSysBox) 53 | { 54 | AROS_LIBFUNC_INIT 55 | #else 56 | void FbxGetUpTime( 57 | REG(a0, struct FbxFS *fs), 58 | REG(a1, struct timeval *tv), 59 | REG(a6, struct FileSysBoxBase *libBase)) 60 | { 61 | #endif 62 | _FbxGetUpTime(fs, tv); 63 | #ifdef __AROS__ 64 | AROS_LIBFUNC_EXIT 65 | #endif 66 | } 67 | 68 | -------------------------------------------------------------------------------- /src/main/FbxSignalDiskChange.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxSignalDiskChange ****************************** 16 | * 17 | * NAME 18 | * FbxSignalDiskChange -- Signal diskchange to filesystem process. (V53.35) 19 | * 20 | * SYNOPSIS 21 | * void FbxSignalDiskChange(struct FbxFS * fs); 22 | * 23 | * FUNCTION 24 | * Only needed if the standard trackdisk.device method of disk change 25 | * detection (through FBXF_ENABLE_DISK_CHANGE_DETECTION) does not suit 26 | * your filesystem for some reason. 27 | * 28 | * INPUTS 29 | * fs - filesystem handle. 30 | * 31 | * RESULT 32 | * This function does not return a result 33 | * 34 | * EXAMPLE 35 | * 36 | * NOTES 37 | * 38 | * BUGS 39 | * 40 | * SEE ALSO 41 | * 42 | ***************************************************************************** 43 | * 44 | */ 45 | 46 | #ifdef __AROS__ 47 | AROS_LH1(void, FbxSignalDiskChange, 48 | AROS_LHA(struct FbxFS *, fs, A0), 49 | struct FileSysBoxBase *, libBase, 15, FileSysBox) 50 | { 51 | AROS_LIBFUNC_INIT 52 | #else 53 | void FbxSignalDiskChange( 54 | REG(a0, struct FbxFS *fs), 55 | REG(a6, struct FileSysBoxBase *libBase)) 56 | { 57 | #endif 58 | struct Library *SysBase = fs->sysbase; 59 | 60 | ADEBUGF("FbxSignalDiskChange(%#p)\n", fs); 61 | 62 | fs->dosetup = TRUE; 63 | Signal(&fs->thisproc->pr_Task, 1UL << fs->diskchangesig); 64 | 65 | #ifdef __AROS__ 66 | AROS_LIBFUNC_EXIT 67 | #endif 68 | } 69 | 70 | -------------------------------------------------------------------------------- /src/fsclose.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | static void FbxClearArchiveFlags(struct FbxFS *fs, const char *fullpath) { 16 | char pathbuf[FBX_MAX_PATH]; 17 | ULONG prot; 18 | 19 | FbxStrlcpy(fs, pathbuf, fullpath, FBX_MAX_PATH); 20 | do { 21 | prot = FbxGetAmigaProtectionFlags(fs, pathbuf); 22 | if (prot & FIBF_ARCHIVE) { 23 | prot &= ~FIBF_ARCHIVE; 24 | FbxSetAmigaProtectionFlags(fs, pathbuf, prot); 25 | } 26 | } while (FbxParentPath(fs, pathbuf) && !IsRoot(pathbuf)); 27 | } 28 | 29 | int FbxCloseFile(struct FbxFS *fs, struct FbxLock *lock) { 30 | struct Library *SysBase = fs->sysbase; 31 | struct FbxEntry *e; 32 | 33 | PDEBUGF("FbxCloseFile(%#p, %#p)\n", fs, lock); 34 | 35 | CHECKVOLUME(DOSFALSE); 36 | 37 | CHECKLOCK(lock, DOSFALSE); 38 | 39 | e = lock->entry; 40 | 41 | if (lock->fh == NULL) { 42 | // this lock should be ended with FbxUnLockObject() 43 | debugf("FbxCloseFile: lock %#p was never opened!\n", lock); 44 | fs->r2 = ERROR_INVALID_LOCK; 45 | return DOSFALSE; 46 | } 47 | 48 | if (lock->info != NULL) { 49 | Fbx_release(fs, e->path, lock->info); 50 | FreeFuseFileInfo(fs, lock->info); 51 | lock->info = NULL; 52 | } 53 | 54 | lock->fh = NULL; 55 | 56 | if (lock->fsvol == fs->currvol && (lock->flags & LOCKFLAG_MODIFIED)) { 57 | FbxClearArchiveFlags(fs, e->path); 58 | FbxDoNotify(fs, e->path); 59 | FbxSetModifyState(fs, 1); 60 | } 61 | 62 | FbxEndLock(fs, lock); 63 | FbxCleanupEntry(fs, e); 64 | 65 | fs->r2 = 0; 66 | return DOSTRUE; 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/fsopenfromlock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include 13 | 14 | static int Fbx_open(struct FbxFS *fs, const char *path, struct fuse_file_info *fi) 15 | { 16 | ODEBUGF("Fbx_open(%#p, '%s', %#p)\n", fs, path, fi); 17 | 18 | return FSOP open(path, fi, &fs->fcntx); 19 | } 20 | 21 | int FbxOpenLock(struct FbxFS *fs, struct FileHandle *fh, struct FbxLock *lock) { 22 | struct Library *SysBase = fs->sysbase; 23 | int error; 24 | 25 | PDEBUGF("FbxOpenLock(%#p, %#p, %#p)\n", fs, fh, lock); 26 | 27 | CHECKVOLUME(DOSFALSE); 28 | 29 | CHECKLOCK(lock, DOSFALSE); 30 | 31 | if (lock->fsvol != fs->currvol) { 32 | fs->r2 = ERROR_NO_DISK; 33 | return DOSFALSE; 34 | } 35 | 36 | if (lock->entry->type != ETYPE_FILE) { 37 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 38 | return DOSFALSE; 39 | } 40 | 41 | if (lock->info != NULL) { 42 | fs->r2 = ERROR_OBJECT_IN_USE; 43 | return DOSFALSE; 44 | } 45 | 46 | lock->info = AllocFuseFileInfo(fs); 47 | if (lock->info == NULL) { 48 | fs->r2 = ERROR_NO_FREE_STORE; 49 | return DOSFALSE; 50 | } 51 | bzero(lock->info, sizeof(*lock->info)); 52 | 53 | if (fs->currvol->vflags & FBXVF_READ_ONLY) 54 | lock->info->flags = O_RDONLY; 55 | else 56 | lock->info->flags = O_RDWR; 57 | 58 | error = Fbx_open(fs, lock->entry->path, lock->info); 59 | if (error) { 60 | FreeFuseFileInfo(fs, lock->info); 61 | lock->info = NULL; 62 | fs->r2 = FbxFuseErrno2Error(error); 63 | return DOSFALSE; 64 | } 65 | 66 | lock->fh = fh; 67 | fh->fh_Arg1 = (SIPTR)MKBADDR(lock); 68 | 69 | fs->r2 = 0; 70 | return DOSTRUE; 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/main/FbxGetSysTime.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxGetSysTime ****************************************** 16 | * 17 | * NAME 18 | * FbxGetSysTime -- Get the current system time 19 | * 20 | * SYNOPSIS 21 | * void FbxGetSysTime(struct FbxFS *fs, struct TimeVal *tv); 22 | * 23 | * FUNCTION 24 | * Reads the current system time and stores it in the supplied 25 | * TimeVal structure. Basically just a convenient way to call 26 | * GetSysTime() from a filesysbox filesystem that doesn't require 27 | * the "timer.device" to be opened again. 28 | * 29 | * INPUTS 30 | * fs - The result of FbxSetupFS(). 31 | * tv - TimeVal structure to store the time in. 32 | * 33 | * RESULT 34 | * This function does not return a result 35 | * 36 | * EXAMPLE 37 | * 38 | * NOTES 39 | * 40 | * BUGS 41 | * 42 | * SEE ALSO 43 | * 44 | ***************************************************************************** 45 | * 46 | */ 47 | 48 | #ifdef __AROS__ 49 | AROS_LH2(void, FbxGetSysTime, 50 | AROS_LHA(struct FbxFS *, fs, A0), 51 | AROS_LHA(struct timeval *, tv, A1), 52 | struct FileSysBoxBase *, libBase, 19, FileSysBox) 53 | { 54 | AROS_LIBFUNC_INIT 55 | #else 56 | void FbxGetSysTime( 57 | REG(a0, struct FbxFS *fs), 58 | REG(a1, struct timeval *tv), 59 | REG(a6, struct FileSysBoxBase *libBase)) 60 | { 61 | #endif 62 | struct Device *TimerBase = fs->timerbase; 63 | GetSysTime(tv); 64 | #ifdef __AROS__ 65 | AROS_LIBFUNC_EXIT 66 | #endif 67 | } 68 | 69 | -------------------------------------------------------------------------------- /include/clib/filesysbox_protos.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated header (sfdc 1.12)! Do not edit! */ 2 | 3 | #ifndef CLIB_FILESYSBOX_PROTOS_H 4 | #define CLIB_FILESYSBOX_PROTOS_H 5 | 6 | /* 7 | ** $VER: filesysbox_protos.h $Id$ $Id$ 8 | ** 9 | ** C prototypes. For use with 32 bit integers only. 10 | ** 11 | ** Copyright (c) 2001 Amiga, Inc. 12 | ** All Rights Reserved 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif /* __cplusplus */ 24 | 25 | 26 | /* "filesysbox.library" */ 27 | APTR FbxQueryMountMsg(struct Message * msg, LONG attr); 28 | struct FbxFS * FbxSetupFS(struct Message * msg, const struct TagItem * tags, const struct fuse_operations * ops, LONG opssize, APTR udata); 29 | LONG FbxEventLoop(struct FbxFS * fs); 30 | void FbxCleanupFS(struct FbxFS * fs); 31 | void FbxReturnMountMsg(struct Message * msg, SIPTR r1, SIPTR r2); 32 | LONG FbxFuseVersion(void); 33 | LONG FbxVersion(void); 34 | void FbxSetSignalCallback(struct FbxFS * fs, FbxSignalCallbackFunc func, ULONG signals); 35 | struct FbxTimerCallbackData * FbxInstallTimerCallback(struct FbxFS * fs, FbxTimerCallbackFunc func, ULONG period); 36 | void FbxUninstallTimerCallback(struct FbxFS * fs, struct FbxTimerCallbackData * cb); 37 | void FbxSignalDiskChange(struct FbxFS * fs); 38 | void FbxCopyStringBSTRToC(BSTR src, STRPTR dst, ULONG size); 39 | void FbxCopyStringCToBSTR(CONST_STRPTR src, BSTR dst, ULONG size); 40 | void FbxQueryFS(struct FbxFS * fs, const struct TagItem * tags); 41 | void FbxQueryFSTags(struct FbxFS * fs, Tag tags, ...); 42 | void FbxGetSysTime(struct FbxFS * fs, struct timeval * tv); 43 | void FbxGetUpTime(struct FbxFS * fs, struct timeval * tv); 44 | 45 | #ifdef __cplusplus 46 | } 47 | #endif /* __cplusplus */ 48 | 49 | #endif /* CLIB_FILESYSBOX_PROTOS_H */ 50 | -------------------------------------------------------------------------------- /src/xattrs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | #ifndef ENODATA 16 | #define ENODATA ENOENT 17 | #endif 18 | 19 | ULONG FbxGetAmigaProtectionFlags(struct FbxFS *fs, const char *fullpath) { 20 | char buffer[4]; 21 | int res, i; 22 | ULONG prot = 0; 23 | 24 | res = Fbx_getxattr(fs, fullpath, fs->xattr_amiga_protection, buffer, sizeof(buffer)); 25 | if (res == 4) { 26 | for (i = 0; i < 4; i++) { 27 | switch (buffer[i]) { 28 | case 'h': prot |= FIBF_HOLD; break; 29 | case 's': prot |= FIBF_SCRIPT; break; 30 | case 'p': prot |= FIBF_PURE; break; 31 | case 'a': prot |= FIBF_ARCHIVE; break; 32 | } 33 | } 34 | } 35 | 36 | return prot; 37 | } 38 | 39 | int FbxSetAmigaProtectionFlags(struct FbxFS *fs, const char *fullpath, ULONG prot) { 40 | int error; 41 | 42 | if (prot & (FIBF_HOLD|FIBF_SCRIPT|FIBF_PURE|FIBF_ARCHIVE)) { 43 | char buffer[4]; 44 | buffer[0] = (prot & FIBF_HOLD ) ? 'h' : '-'; 45 | buffer[1] = (prot & FIBF_SCRIPT ) ? 's' : '-'; 46 | buffer[2] = (prot & FIBF_PURE ) ? 'p' : '-'; 47 | buffer[3] = (prot & FIBF_ARCHIVE) ? 'a' : '-'; 48 | error = Fbx_setxattr(fs, fullpath, fs->xattr_amiga_protection, buffer, 4, 0); 49 | } else { 50 | error = Fbx_removexattr(fs, fullpath, fs->xattr_amiga_protection); 51 | if (error == -ENODATA) 52 | error = 0; 53 | } 54 | 55 | return error; 56 | } 57 | 58 | void FbxGetComment(struct FbxFS *fs, const char *fullpath, char *comment, size_t size) { 59 | int res; 60 | 61 | res = Fbx_getxattr(fs, fullpath, fs->xattr_amiga_comment, comment, size-1); 62 | if (res < 0) { 63 | comment[0] = '\0'; 64 | return; 65 | } 66 | 67 | comment[min(res, size-1)] = '\0'; 68 | if (!FbxCheckString(fs, comment)) { 69 | comment[0] = '\0'; 70 | return; 71 | } 72 | } 73 | 74 | -------------------------------------------------------------------------------- /src/fsdie.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | int FbxDie(struct FbxFS *fs) { 14 | struct Library *SysBase = fs->sysbase; 15 | struct MinNode *chain; 16 | struct Message *msg; 17 | 18 | /* check if shutdown is already in progress */ 19 | if (fs->shutdown) { 20 | fs->r2 = ERROR_ACTION_NOT_KNOWN; 21 | return DOSFALSE; 22 | } 23 | 24 | if (fs->devnode != NULL) { 25 | fs->devnode->dn_Task = NULL; 26 | fs->devnode = NULL; 27 | } 28 | 29 | FbxCleanupVolume(fs); 30 | 31 | while ((chain = (struct MinNode *)RemHead((struct List *)&fs->volumelist)) != NULL) { 32 | struct FbxVolume *vol = FSVOLUMEFROMFSCHAIN(chain); 33 | 34 | while ((chain = (struct MinNode *)RemHead((struct List *)&vol->locklist)) != NULL) { 35 | struct FbxLock *lock = FSLOCKFROMVOLUMECHAIN(chain); 36 | 37 | Remove((struct Node *)&lock->entrychain); 38 | FbxCleanupEntry(fs, lock->entry); 39 | lock->entry = NULL; 40 | 41 | lock->fs = NULL; /* invalidate lock */ 42 | 43 | /* if (lock->fh != NULL) { 44 | FbxCollectFH(fs, lock->fh); 45 | 46 | FreeFbxLock(lock); 47 | } else */ { 48 | FbxCollectLock(fs, lock); 49 | } 50 | } 51 | 52 | while ((chain = (struct MinNode *)RemHead((struct List *)&vol->notifylist)) != NULL) { 53 | struct FbxNotifyNode *nn = FSNOTIFYNODEFROMVOLUMECHAIN(chain); 54 | 55 | Remove((struct Node *)&nn->chain); 56 | if (nn->entry != NULL) { 57 | FbxCleanupEntry(fs, nn->entry); 58 | nn->entry = NULL; 59 | } 60 | 61 | FbxCollectNotifyNode(fs, nn); 62 | } 63 | 64 | FreeFbxVolume(vol); 65 | } 66 | 67 | /* Redirect remaining packets to the lock handler process */ 68 | while ((msg = GetMsg(fs->fsport)) != NULL) { 69 | PutMsg(fs->lhproc_port, msg); 70 | } 71 | 72 | fs->shutdown = TRUE; 73 | 74 | fs->r2 = 0; 75 | return DOSTRUE; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/fssetownerinfo.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_chown(struct FbxFS *fs, const char *path, uid_t uid, gid_t gid) 14 | { 15 | ODEBUGF("Fbx_chown(%#p, '%s', %#x, %#x)\n", fs, path, uid, gid); 16 | 17 | return FSOP chown(path, uid, gid, &fs->fcntx); 18 | } 19 | 20 | static uid_t FbxAmiga2UnixOwner(const UWORD owner) { 21 | if (owner == DOS_OWNER_ROOT) return (uid_t)0; 22 | else if (owner == DOS_OWNER_NONE) return (uid_t)-2; 23 | else return (uid_t)owner; 24 | } 25 | 26 | int FbxSetOwnerInfo(struct FbxFS *fs, struct FbxLock *lock, const char *name, 27 | UWORD uid, UWORD gid) 28 | { 29 | int error; 30 | char fullpath[FBX_MAX_PATH]; 31 | #ifdef ENABLE_CHARSET_CONVERSION 32 | char fsname[FBX_MAX_NAME]; 33 | #endif 34 | 35 | PDEBUGF("FbxSetOwnerInfo(%#p, %#p, '%s', %#x, %#x)\n", fs, lock, name, uid, gid); 36 | 37 | CHECKVOLUME(DOSFALSE); 38 | CHECKWRITABLE(DOSFALSE); 39 | 40 | if (lock != NULL) { 41 | CHECKLOCK(lock, DOSFALSE); 42 | 43 | if (lock->fsvol != fs->currvol) { 44 | fs->r2 = ERROR_NO_DISK; 45 | return DOSFALSE; 46 | } 47 | } 48 | 49 | #ifdef ENABLE_CHARSET_CONVERSION 50 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 51 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 52 | fs->r2 = ERROR_LINE_TOO_LONG; 53 | return DOSFALSE; 54 | } 55 | name = fsname; 56 | } 57 | #else 58 | CHECKSTRING(name, DOSFALSE); 59 | #endif 60 | 61 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 62 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 63 | return DOSFALSE; 64 | } 65 | 66 | error = Fbx_chown(fs, fullpath, FbxAmiga2UnixOwner(uid), FbxAmiga2UnixOwner(gid)); 67 | if (error) { 68 | fs->r2 = FbxFuseErrno2Error(error); 69 | return DOSFALSE; 70 | } 71 | 72 | FbxSetModifyState(fs, 1); 73 | 74 | fs->r2 = 0; 75 | return DOSTRUE; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /src/main/FbxReturnMountMsg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxReturnMountMsg ******************************** 16 | * 17 | * NAME 18 | * FbxReturnMountMsg -- Return mount message 19 | * 20 | * SYNOPSIS 21 | * void FbxReturnMountMsg(struct Message *msg, LONG r1, LONG r2); 22 | * 23 | * FUNCTION 24 | * Returns mount message given to filesystem at startup. 25 | * Should never be called by filesystem unless there is a 26 | * valid msg AND FbxSetupFS() was never called. 27 | * 28 | * INPUTS 29 | * msg - mount message 30 | * r1 - DOSTRUE for success, DOSFALSE for failure. 31 | * r2 - error code if failure, else 0. 32 | * 33 | * RESULT 34 | * This function does not return a result 35 | * 36 | * EXAMPLE 37 | * 38 | * NOTES 39 | * 40 | * BUGS 41 | * 42 | * SEE ALSO 43 | * 44 | ***************************************************************************** 45 | * 46 | */ 47 | 48 | #ifdef __AROS__ 49 | AROS_LH3(void, FbxReturnMountMsg, 50 | AROS_LHA(struct Message *, msg, A0), 51 | AROS_LHA(SIPTR, r1, D0), 52 | AROS_LHA(SIPTR, r2, D1), 53 | struct FileSysBoxBase *, libBase, 9, FileSysBox) 54 | { 55 | AROS_LIBFUNC_INIT 56 | #else 57 | void FbxReturnMountMsg( 58 | REG(a0, struct Message *msg), 59 | REG(d0, SIPTR r1), 60 | REG(d1, SIPTR r2), 61 | REG(a6, struct FileSysBoxBase *libBase)) 62 | { 63 | #endif 64 | struct Library *DOSBase = libBase->dosbase; 65 | 66 | ADEBUGF("FbxReturnMountMsg(%#p, %#p, %#p)\n", msg, (APTR)r1, (APTR)r2); 67 | 68 | if (msg != NULL) 69 | { 70 | struct DosPacket *pkt = (struct DosPacket *)msg->mn_Node.ln_Name; 71 | 72 | ReplyPkt(pkt, r1, r2); 73 | } 74 | 75 | #ifdef __AROS__ 76 | AROS_LIBFUNC_EXIT 77 | #endif 78 | } 79 | 80 | -------------------------------------------------------------------------------- /src/fscreatesoftlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_symlink(struct FbxFS *fs, const char *dest, const char *path) 14 | { 15 | ODEBUGF("Fbx_symlink(%#p, '%s', '%s')\n", fs, path, dest); 16 | 17 | return FSOP symlink(dest, path, &fs->fcntx); 18 | } 19 | 20 | int FbxMakeSoftLink(struct FbxFS *fs, struct FbxLock *lock, const char *name, 21 | const char *softname) 22 | { 23 | int error; 24 | char fullpath[FBX_MAX_PATH]; 25 | #ifdef ENABLE_CHARSET_CONVERSION 26 | char fsname[FBX_MAX_NAME]; 27 | char fssoftname[FBX_MAX_PATH]; 28 | #endif 29 | 30 | PDEBUGF("FbxMakeSoftlink(%#p, %#p, '%s', '%s')\n", fs, lock, name, softname); 31 | 32 | CHECKVOLUME(DOSFALSE); 33 | CHECKWRITABLE(DOSFALSE); 34 | 35 | if (lock != NULL) { 36 | CHECKLOCK(lock, DOSFALSE); 37 | 38 | if (lock->fsvol != fs->currvol) { 39 | fs->r2 = ERROR_NO_DISK; 40 | return DOSFALSE; 41 | } 42 | } 43 | 44 | #ifdef ENABLE_CHARSET_CONVERSION 45 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 46 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 47 | fs->r2 = ERROR_LINE_TOO_LONG; 48 | return DOSFALSE; 49 | } 50 | name = fsname; 51 | if (FbxLocalToUTF8(fs, fssoftname, softname, FBX_MAX_PATH) >= FBX_MAX_PATH) { 52 | fs->r2 = ERROR_LINE_TOO_LONG; 53 | return DOSFALSE; 54 | } 55 | softname = fssoftname; 56 | } 57 | #else 58 | CHECKSTRING(name, DOSFALSE); 59 | CHECKSTRING(softname, DOSFALSE); 60 | #endif 61 | 62 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 63 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 64 | return DOSFALSE; 65 | } 66 | 67 | error = Fbx_symlink(fs, softname, fullpath); 68 | if (error) { 69 | fs->r2 = FbxFuseErrno2Error(error); 70 | return DOSFALSE; 71 | } 72 | 73 | FbxDoNotify(fs, fullpath); 74 | 75 | FbxSetModifyState(fs, 1); 76 | 77 | fs->r2 = 0; 78 | return DOSTRUE; 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/fslock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | 14 | struct FbxLock *FbxLocateObject(struct FbxFS *fs, struct FbxLock *lock, 15 | const char *name, int lockmode) 16 | { 17 | struct fbx_stat statbuf; 18 | int error; 19 | LONG ntype; 20 | struct FbxEntry *e; 21 | struct FbxLock *lock2; 22 | char fullpath[FBX_MAX_PATH]; 23 | #ifdef ENABLE_CHARSET_CONVERSION 24 | char fsname[FBX_MAX_NAME]; 25 | #endif 26 | 27 | PDEBUGF("FbxLocateObject(%#p, %#p, '%s', %d)\n", fs, lock, name, lockmode); 28 | 29 | CHECKVOLUME(NULL); 30 | 31 | if (lock != NULL) { 32 | CHECKLOCK(lock, NULL); 33 | 34 | if (lock->fsvol != fs->currvol) { 35 | fs->r2 = ERROR_NO_DISK; 36 | return NULL; 37 | } 38 | } 39 | 40 | #ifdef ENABLE_CHARSET_CONVERSION 41 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 42 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 43 | fs->r2 = ERROR_LINE_TOO_LONG; 44 | return NULL; 45 | } 46 | name = fsname; 47 | } 48 | #else 49 | CHECKSTRING(name, NULL); 50 | #endif 51 | 52 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 53 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 54 | return NULL; 55 | } 56 | 57 | error = Fbx_getattr(fs, fullpath, &statbuf); 58 | if (error) { 59 | fs->r2 = FbxFuseErrno2Error(error); 60 | return NULL; 61 | } 62 | 63 | if (S_ISLNK(statbuf.st_mode)) { 64 | fs->r2 = ERROR_IS_SOFT_LINK; 65 | return NULL; 66 | } else if (S_ISREG(statbuf.st_mode)) { 67 | ntype = ETYPE_FILE; 68 | } else { 69 | ntype = ETYPE_DIR; 70 | } 71 | 72 | e = FbxFindEntry(fs, fullpath); 73 | if (e == NULL) { 74 | e = FbxSetupEntry(fs, fullpath, ntype, statbuf.st_ino); 75 | if (e == NULL) return NULL; 76 | } 77 | 78 | lock2 = FbxLockEntry(fs, e, lockmode); 79 | if (lock2 == NULL) { 80 | FbxCleanupEntry(fs, e); 81 | return NULL; 82 | } 83 | 84 | fs->r2 = 0; 85 | return lock2; 86 | } 87 | 88 | -------------------------------------------------------------------------------- /src/main/FbxUninstallTimerCallback.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxUninstallTimerCallback ************************ 16 | * 17 | * NAME 18 | * FbxUninstallTimerCallback -- Uninstall timer callback. (V53.23) 19 | * 20 | * SYNOPSIS 21 | * void FbxUninstallTimerCallback(struct FbxFS * fs, 22 | * struct FbxTimerCallbackData * cb); 23 | * 24 | * FUNCTION 25 | * Use to remove a timer callback installed by FbxInstallTimerCallback(). 26 | * 27 | * INPUTS 28 | * fs - The result of FbxSetupFS(). 29 | * cb - The result of FbxInstallTimerCallback(). 30 | * 31 | * RESULT 32 | * This function does not return a result 33 | * 34 | * EXAMPLE 35 | * 36 | * NOTES 37 | * Passing a NULL pointer as cb is safe and will do nothing. 38 | * 39 | * BUGS 40 | * 41 | * SEE ALSO 42 | * FbxInstallTimerCallback() 43 | * 44 | ***************************************************************************** 45 | * 46 | */ 47 | 48 | #ifdef __AROS__ 49 | AROS_LH2(void, FbxUninstallTimerCallback, 50 | AROS_LHA(struct FbxFS *, fs, A0), 51 | AROS_LHA(struct FbxTimerCallbackData *, cb, A1), 52 | struct FileSysBoxBase *, libBase, 14, FileSysBox) 53 | { 54 | AROS_LIBFUNC_INIT 55 | #else 56 | void FbxUninstallTimerCallback( 57 | REG(a0, struct FbxFS *fs), 58 | REG(a1, struct FbxTimerCallbackData *cb), 59 | REG(a6, struct FileSysBoxBase *libBase)) 60 | { 61 | #endif 62 | ADEBUGF("FbxUninstallTimerCallback(%#p, %#p)\n", fs, cb); 63 | 64 | if (fs != NULL && cb != NULL) { 65 | struct Library *SysBase = fs->sysbase; 66 | 67 | ObtainSemaphore(&fs->fssema); 68 | Remove((struct Node *)&cb->fschain); 69 | ReleaseSemaphore(&fs->fssema); 70 | 71 | FreeFbxTimerCallbackData(fs, cb); 72 | } 73 | 74 | #ifdef __AROS__ 75 | AROS_LIBFUNC_EXIT 76 | #endif 77 | } 78 | 79 | -------------------------------------------------------------------------------- /src/filesysbox_vectors.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #include "filesysbox_vectors.h" 9 | 10 | #ifdef __AROS__ 11 | #define LibOpen AROS_SLIB_ENTRY(LibOpen,FileSysBox,1) 12 | #define LibClose AROS_SLIB_ENTRY(LibClose,FileSysBox,2) 13 | #define LibExpunge AROS_SLIB_ENTRY(LibExpunge,FileSysBox,3) 14 | #define LibReserved AROS_SLIB_ENTRY(LibReserved,FileSysBox,4) 15 | #define FbxQueryMountMsg AROS_SLIB_ENTRY(FbxQueryMountMsg,FileSysBox,5) 16 | #define FbxSetupFS AROS_SLIB_ENTRY(FbxSetupFS,FileSysBox,6) 17 | #define FbxEventLoop AROS_SLIB_ENTRY(FbxEventLoop,FileSysBox,7) 18 | #define FbxCleanupFS AROS_SLIB_ENTRY(FbxCleanupFS,FileSysBox,8) 19 | #define FbxReturnMountMsg AROS_SLIB_ENTRY(FbxReturnMountMsg,FileSysBox,9) 20 | #define FbxFuseVersion AROS_SLIB_ENTRY(FbxFuseVersion,FileSysBox,10) 21 | #define FbxVersion AROS_SLIB_ENTRY(FbxVersion,FileSysBox,11) 22 | #define FbxSetSignalCallback AROS_SLIB_ENTRY(FbxSetSignalCallback,FileSysBox,12) 23 | #define FbxInstallTimerCallback AROS_SLIB_ENTRY(FbxInstallTimerCallback,FileSysBox,13) 24 | #define FbxUninstallTimerCallback AROS_SLIB_ENTRY(FbxUninstallTimerCallback,FileSysBox,14) 25 | #define FbxSignalDiskChange AROS_SLIB_ENTRY(FbxSignalDiskChange,FileSysBox,15) 26 | #define FbxCopyStringBSTRToC AROS_SLIB_ENTRY(FbxCopyStringBSTRToC,FileSysBox,16) 27 | #define FbxCopyStringCToBSTR AROS_SLIB_ENTRY(FbxCopyStringCToBSTR,FileSysBox,17) 28 | #define FbxQueryFS AROS_SLIB_ENTRY(FbxQueryFS,FileSysBox,18) 29 | #define FbxGetSysTime AROS_SLIB_ENTRY(FbxGetSysTime,FileSysBox,19) 30 | #define FbxGetUpTime AROS_SLIB_ENTRY(FbxGetUpTime,FileSysBox,20) 31 | #endif 32 | 33 | static const CONST_APTR LibVectors[] = { 34 | LibOpen, 35 | LibClose, 36 | LibExpunge, 37 | LibReserved, 38 | FbxQueryMountMsg, 39 | FbxSetupFS, 40 | FbxEventLoop, 41 | FbxCleanupFS, 42 | FbxReturnMountMsg, 43 | FbxFuseVersion, 44 | FbxVersion, 45 | FbxSetSignalCallback, 46 | FbxInstallTimerCallback, 47 | FbxUninstallTimerCallback, 48 | FbxSignalDiskChange, 49 | FbxCopyStringBSTRToC, 50 | FbxCopyStringCToBSTR, 51 | FbxQueryFS, 52 | FbxGetSysTime, 53 | FbxGetUpTime, 54 | (APTR)-1 55 | }; 56 | 57 | -------------------------------------------------------------------------------- /src/fscreatehardlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_link(struct FbxFS *fs, const char *dest, const char *path) 14 | { 15 | ODEBUGF("Fbx_link(%#p, '%s', '%s')\n", fs, dest, path); 16 | 17 | return FSOP link(dest, path, &fs->fcntx); 18 | } 19 | 20 | int FbxMakeHardLink(struct FbxFS *fs, struct FbxLock *lock, const char *name, 21 | struct FbxLock *lock2) 22 | { 23 | int error; 24 | char fullpath[FBX_MAX_PATH]; 25 | char fullpath2[FBX_MAX_PATH]; 26 | #ifdef ENABLE_CHARSET_CONVERSION 27 | char fsname[FBX_MAX_NAME]; 28 | #endif 29 | 30 | PDEBUGF("FbxMakeHardlink(%#p, %#p, '%s', %#p)\n", fs, lock, name, lock2); 31 | 32 | CHECKVOLUME(DOSFALSE); 33 | CHECKWRITABLE(DOSFALSE); 34 | 35 | if (lock != NULL) { 36 | CHECKLOCK(lock, DOSFALSE); 37 | 38 | if (lock->fsvol != fs->currvol) { 39 | fs->r2 = ERROR_NO_DISK; 40 | return DOSFALSE; 41 | } 42 | } 43 | 44 | #ifdef ENABLE_CHARSET_CONVERSION 45 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 46 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 47 | fs->r2 = ERROR_LINE_TOO_LONG; 48 | return DOSFALSE; 49 | } 50 | name = fsname; 51 | } 52 | #else 53 | CHECKLOCK(lock2, DOSFALSE); 54 | #endif 55 | 56 | CHECKSTRING(name, DOSFALSE); 57 | 58 | if (lock2->fsvol != fs->currvol) { 59 | fs->r2 = ERROR_NO_DISK; 60 | return DOSFALSE; 61 | } 62 | 63 | if (!FbxLockName2Path(fs, lock, name, fullpath) || 64 | !FbxLockName2Path(fs, lock2, "", fullpath2)) 65 | { 66 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 67 | return DOSFALSE; 68 | } 69 | 70 | if (FbxIsParent(fs, fullpath2, fullpath)) { 71 | fs->r2 = ERROR_OBJECT_IN_USE; 72 | return DOSFALSE; 73 | } 74 | 75 | error = Fbx_link(fs, fullpath2, fullpath); 76 | if (error) { 77 | fs->r2 = FbxFuseErrno2Error(error); 78 | return DOSFALSE; 79 | } 80 | 81 | FbxDoNotify(fs, fullpath); 82 | 83 | FbxSetModifyState(fs, 1); 84 | 85 | fs->r2 = 0; 86 | return DOSTRUE; 87 | } 88 | 89 | -------------------------------------------------------------------------------- /src/fssetcomment.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | #include 15 | 16 | #ifndef ENODATA 17 | #define ENODATA ENOENT 18 | #endif 19 | 20 | int FbxSetComment(struct FbxFS *fs, struct FbxLock *lock, const char *name, 21 | const char *comment) 22 | { 23 | int error; 24 | char fullpath[FBX_MAX_PATH]; 25 | #ifdef ENABLE_CHARSET_CONVERSION 26 | char fsname[FBX_MAX_NAME]; 27 | char fscomment[FBX_MAX_COMMENT]; 28 | #endif 29 | 30 | PDEBUGF("FbxSetComment(%#p, %#p, '%s', '%s')\n", fs, lock, name, comment); 31 | 32 | CHECKVOLUME(DOSFALSE); 33 | CHECKWRITABLE(DOSFALSE); 34 | 35 | if (lock != NULL) { 36 | CHECKLOCK(lock, DOSFALSE); 37 | 38 | if (lock->fsvol != fs->currvol) { 39 | fs->r2 = ERROR_NO_DISK; 40 | return DOSFALSE; 41 | } 42 | } 43 | 44 | #ifdef ENABLE_CHARSET_CONVERSION 45 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 46 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 47 | fs->r2 = ERROR_LINE_TOO_LONG; 48 | return DOSFALSE; 49 | } 50 | name = fsname; 51 | if (FbxLocalToUTF8(fs, fscomment, comment, FBX_MAX_COMMENT) >= FBX_MAX_COMMENT) { 52 | fs->r2 = ERROR_LINE_TOO_LONG; 53 | return DOSFALSE; 54 | } 55 | comment = fscomment; 56 | } 57 | #else 58 | CHECKSTRING(name, DOSFALSE); 59 | CHECKSTRING(comment, DOSFALSE); 60 | #endif 61 | 62 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 63 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 64 | return DOSFALSE; 65 | } 66 | 67 | if (comment[0] != '\0') { 68 | error = Fbx_setxattr(fs, fullpath, fs->xattr_amiga_comment, 69 | comment, strlen(comment), 0); 70 | } else { 71 | error = Fbx_removexattr(fs, fullpath, fs->xattr_amiga_comment); 72 | if (error == -ENODATA) 73 | error = 0; 74 | } 75 | if (error) { 76 | fs->r2 = FbxFuseErrno2Error(error); 77 | return DOSFALSE; 78 | } 79 | 80 | FbxSetModifyState(fs, 1); 81 | 82 | fs->r2 = 0; 83 | return DOSTRUE; 84 | } 85 | 86 | -------------------------------------------------------------------------------- /src/main/FbxSetSignalCallback.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxSetSignalCallback ***************************** 16 | * 17 | * NAME 18 | * FbxSetSignalCallback -- Set callback function for custom signals. 19 | * (V53.23) 20 | * 21 | * SYNOPSIS 22 | * void FbxSetSignalCallback(struct FbxFS * fs, 23 | * FbxSignalCallbackFunc func, ULONG signals); 24 | * 25 | * FUNCTION 26 | * Adds a callback function that will get called when the main filesystem 27 | * process receives one or more of the specified signals. 28 | * 29 | * INPUTS 30 | * fs - The result of FbxSetupFS(). 31 | * func - Callback function. 32 | * signals - Signals to call on. 33 | * 34 | * RESULT 35 | * This function does not return a result 36 | * 37 | * EXAMPLE 38 | * 39 | * NOTES 40 | * 41 | * BUGS 42 | * 43 | * SEE ALSO 44 | * 45 | ***************************************************************************** 46 | * 47 | */ 48 | 49 | #ifdef __AROS__ 50 | AROS_LH3(void, FbxSetSignalCallback, 51 | AROS_LHA(struct FbxFS *, fs, A0), 52 | AROS_LHA(FbxSignalCallbackFunc, func, A1), 53 | AROS_LHA(ULONG, signals, D0), 54 | struct FileSysBoxBase *, libBase, 12, FileSysBox) 55 | { 56 | AROS_LIBFUNC_INIT 57 | #else 58 | void FbxSetSignalCallback( 59 | REG(a0, struct FbxFS *fs), 60 | REG(a1, FbxSignalCallbackFunc func), 61 | REG(d0, ULONG signals), 62 | REG(a6, struct FileSysBoxBase *libBase)) 63 | { 64 | #endif 65 | ADEBUGF("FbxSetSignalCallback(%#p, %#p, 0x%lx)\n", fs, func, signals); 66 | 67 | if (fs != NULL) { 68 | struct Library *SysBase = fs->sysbase; 69 | 70 | ObtainSemaphore(&fs->fssema); 71 | 72 | fs->signalcallbackfunc = func; 73 | fs->signalcallbacksignals = signals; 74 | 75 | ReleaseSemaphore(&fs->fssema); 76 | } 77 | 78 | #ifdef __AROS__ 79 | AROS_LIBFUNC_EXIT 80 | #endif 81 | } 82 | 83 | -------------------------------------------------------------------------------- /src/fuse_stubs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | 14 | int Fbx_getattr(struct FbxFS *fs, const char *path, struct fbx_stat *stat) 15 | { 16 | ODEBUGF("Fbx_getattr(%#p, '%s', %#p)\n", fs, path, stat); 17 | 18 | return FSOP getattr(path, stat, &fs->fcntx); 19 | } 20 | 21 | int Fbx_statfs(struct FbxFS *fs, const char *name, struct statvfs *stat) 22 | { 23 | ODEBUGF("Fbx_statfs(%#p, '%s', %#p)\n", fs, name, stat); 24 | 25 | return FSOP statfs(name, stat, &fs->fcntx); 26 | } 27 | 28 | int Fbx_release(struct FbxFS *fs, const char *path, struct fuse_file_info *fi) 29 | { 30 | ODEBUGF("Fbx_release(%#p, '%s', %#p)\n", fs, path, fi); 31 | 32 | return FSOP release(path, fi, &fs->fcntx); 33 | } 34 | 35 | int Fbx_fsync(struct FbxFS *fs, const char *path, int x, struct fuse_file_info *fi) 36 | { 37 | ODEBUGF("Fbx_fsync(%#p, '%s', %d, %#p)\n", fs, path, x, fi); 38 | 39 | return FSOP fsync(path, x, fi, &fs->fcntx); 40 | } 41 | 42 | int Fbx_fgetattr(struct FbxFS *fs, const char *path, struct fbx_stat *stat, 43 | struct fuse_file_info *fi) 44 | { 45 | ODEBUGF("Fbx_fgetattr(%#p, '%s', %#p, %#p)\n", fs, path, stat, fi); 46 | 47 | return FSOP fgetattr(path, stat, fi, &fs->fcntx); 48 | } 49 | 50 | int Fbx_setxattr(struct FbxFS *fs, const char *path, const char *attr, 51 | CONST_APTR buf, size_t len, int flags) 52 | { 53 | ODEBUGF("Fbx_setxattr(%#p, '%s', '%s', %#p, %lu, %d)\n", fs, path, attr, buf, len, flags); 54 | 55 | return FSOP setxattr(path, attr, buf, len, flags, &fs->fcntx); 56 | } 57 | 58 | int Fbx_getxattr(struct FbxFS *fs, const char *path, const char *attr, 59 | APTR buf, size_t len) 60 | { 61 | ODEBUGF("Fbx_getxattr(%#p, '%s', '%s', %#p, %lu)\n", fs, path, attr, buf, len); 62 | 63 | return FSOP getxattr(path, attr, buf, len, &fs->fcntx); 64 | } 65 | 66 | int Fbx_removexattr(struct FbxFS *fs, const char *path, const char *attr) 67 | { 68 | ODEBUGF("Fbx_removexattr(%#p, '%s', '%s')\n", fs, path, attr); 69 | 70 | return FSOP removexattr(path, attr, &fs->fcntx); 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/fsreadlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | static int Fbx_readlink(struct FbxFS *fs, const char *path, char *buf, size_t buflen) 16 | { 17 | ODEBUGF("Fbx_readlink(%#p, '%s', %#p, %lu)\n", fs, path, buf, buflen); 18 | 19 | return FSOP readlink(path, buf, buflen, &fs->fcntx); 20 | } 21 | 22 | int FbxReadLink(struct FbxFS *fs, struct FbxLock *lock, const char *name, 23 | char *buffer, int size) 24 | { 25 | struct fbx_stat statbuf; 26 | int error, len; 27 | char fullpath[FBX_MAX_PATH]; 28 | char softname[FBX_MAX_PATH]; 29 | #ifdef ENABLE_CHARSET_CONVERSION 30 | char fsname[FBX_MAX_NAME]; 31 | #endif 32 | 33 | PDEBUGF("FbxReadLink(%#p, %#p, '%s', %#p, %d)\n", fs, lock, name, buffer, size); 34 | 35 | CHECKVOLUME(-1); 36 | 37 | if (lock != NULL) { 38 | CHECKLOCK(lock, -1); 39 | 40 | if (lock->fsvol != fs->currvol) { 41 | fs->r2 = ERROR_NO_DISK; 42 | return -1; 43 | } 44 | } 45 | 46 | #ifdef ENABLE_CHARSET_CONVERSION 47 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 48 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 49 | fs->r2 = ERROR_LINE_TOO_LONG; 50 | return -1; 51 | } 52 | name = fsname; 53 | } 54 | #else 55 | CHECKSTRING(name, -1); 56 | #endif 57 | 58 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 59 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 60 | return -1; 61 | } 62 | 63 | error = Fbx_getattr(fs, fullpath, &statbuf); 64 | if (error) { 65 | fs->r2 = FbxFuseErrno2Error(error); 66 | return -1; 67 | } 68 | 69 | // check if it's a soft link 70 | if (!S_ISLNK(statbuf.st_mode)) { 71 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 72 | return -1; 73 | } 74 | 75 | error = Fbx_readlink(fs, fullpath, softname, FBX_MAX_PATH); 76 | if (error) { 77 | fs->r2 = FbxFuseErrno2Error(error); 78 | return -1; 79 | } 80 | 81 | #ifdef ENABLE_CHARSET_CONVERSION 82 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) 83 | len = FbxUTF8ToLocal(fs, buffer, softname, size); 84 | else 85 | len = strlcpy(buffer, softname, size); 86 | #else 87 | len = FbxStrlcpy(fs, buffer, softname, size); 88 | #endif 89 | if (len >= size) { 90 | fs->r2 = ERROR_LINE_TOO_LONG; 91 | return -2; 92 | } 93 | 94 | fs->r2 = 0; 95 | return len; 96 | } 97 | 98 | -------------------------------------------------------------------------------- /src/fscreatedir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | 14 | static int Fbx_mkdir(struct FbxFS *fs, const char *path, mode_t mode) 15 | { 16 | ODEBUGF("Fbx_mkdir(%#p, '%s', 0%o)\n", fs, path, mode); 17 | 18 | return FSOP mkdir(path, mode, &fs->fcntx); 19 | } 20 | 21 | struct FbxLock *FbxCreateDir(struct FbxFS *fs, struct FbxLock *lock, const char *name) { 22 | struct FbxEntry *e; 23 | int error; 24 | struct FbxLock *lock2; 25 | struct fbx_stat statbuf; 26 | char fullpath[FBX_MAX_PATH]; 27 | #ifdef ENABLE_CHARSET_CONVERSION 28 | char fsname[FBX_MAX_NAME]; 29 | #endif 30 | 31 | PDEBUGF("FbxCreateDir(%#p, %#p, '%s')\n", fs, lock, name); 32 | 33 | CHECKVOLUME(NULL); 34 | CHECKWRITABLE(NULL); 35 | 36 | if (lock != NULL) { 37 | CHECKLOCK(lock, NULL); 38 | 39 | if (lock->fsvol != fs->currvol) { 40 | fs->r2 = ERROR_NO_DISK; 41 | return NULL; 42 | } 43 | } 44 | 45 | #ifdef ENABLE_CHARSET_CONVERSION 46 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 47 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 48 | fs->r2 = ERROR_LINE_TOO_LONG; 49 | return NULL; 50 | } 51 | name = fsname; 52 | } 53 | #else 54 | CHECKSTRING(name, NULL); 55 | #endif 56 | 57 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 58 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 59 | return NULL; 60 | } 61 | 62 | e = FbxFindEntry(fs, fullpath); 63 | if (e != NULL) { 64 | fs->r2 = ERROR_OBJECT_EXISTS; 65 | return NULL; 66 | } 67 | 68 | error = Fbx_mkdir(fs, fullpath, DEFAULT_PERMS|S_IFDIR); 69 | if (error) { 70 | fs->r2 = FbxFuseErrno2Error(error); 71 | return NULL; 72 | } 73 | 74 | DEBUGF("FbxCreateDir created dir ok\n"); 75 | 76 | error = Fbx_getattr(fs, fullpath, &statbuf); 77 | if (error) { 78 | fs->r2 = FbxFuseErrno2Error(error); 79 | return NULL; 80 | } 81 | 82 | e = FbxSetupEntry(fs, fullpath, ETYPE_DIR, statbuf.st_ino); 83 | if (e == NULL) return NULL; 84 | 85 | FbxTryResolveNotify(fs, e); 86 | 87 | FbxDoNotify(fs, fullpath); 88 | 89 | lock2 = FbxLockEntry(fs, e, SHARED_LOCK); 90 | if (lock2 == NULL) { 91 | FbxCleanupEntry(fs, e); 92 | return NULL; 93 | } 94 | 95 | FbxSetModifyState(fs, 1); 96 | 97 | fs->r2 = 0; 98 | return lock2; 99 | } 100 | 101 | -------------------------------------------------------------------------------- /src/fssetprotection.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | static int Fbx_chmod(struct FbxFS *fs, const char *path, mode_t mode) 16 | { 17 | ODEBUGF("Fbx_chmod(%#p, '%s', 0%o)\n", fs, path, mode); 18 | 19 | return FSOP chmod(path, mode, &fs->fcntx); 20 | } 21 | 22 | static mode_t FbxProtection2Mode(ULONG prot) { 23 | mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR; 24 | 25 | if (prot & FIBF_READ ) mode &= ~(S_IRUSR); 26 | if (prot & FIBF_WRITE ) mode &= ~(S_IWUSR); 27 | if (prot & FIBF_EXECUTE ) mode &= ~(S_IXUSR); 28 | if (prot & FIBF_GRP_READ ) mode |= S_IRGRP; 29 | if (prot & FIBF_GRP_WRITE ) mode |= S_IWGRP; 30 | if (prot & FIBF_GRP_EXECUTE) mode |= S_IXGRP; 31 | if (prot & FIBF_OTR_READ ) mode |= S_IROTH; 32 | if (prot & FIBF_OTR_WRITE ) mode |= S_IWOTH; 33 | if (prot & FIBF_OTR_EXECUTE) mode |= S_IXOTH; 34 | 35 | return mode; 36 | } 37 | 38 | int FbxSetProtection(struct FbxFS *fs, struct FbxLock *lock, const char *name, ULONG prot) { 39 | int error; 40 | char fullpath[FBX_MAX_PATH]; 41 | #ifdef ENABLE_CHARSET_CONVERSION 42 | char fsname[FBX_MAX_NAME]; 43 | #endif 44 | 45 | PDEBUGF("FbxSetProtection(%#p, %#p, '%s', %#lx)\n", fs, lock, name, prot); 46 | 47 | CHECKVOLUME(DOSFALSE); 48 | CHECKWRITABLE(DOSFALSE); 49 | 50 | if (lock != NULL) { 51 | CHECKLOCK(lock, DOSFALSE); 52 | 53 | if (lock->fsvol != fs->currvol) { 54 | fs->r2 = ERROR_NO_DISK; 55 | return DOSFALSE; 56 | } 57 | } 58 | 59 | #ifdef ENABLE_CHARSET_CONVERSION 60 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 61 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 62 | fs->r2 = ERROR_LINE_TOO_LONG; 63 | return DOSFALSE; 64 | } 65 | name = fsname; 66 | } 67 | #else 68 | CHECKSTRING(name, DOSFALSE); 69 | #endif 70 | 71 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 72 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 73 | return DOSFALSE; 74 | } 75 | 76 | error = Fbx_chmod(fs, fullpath, FbxProtection2Mode(prot)); 77 | if (error) { 78 | fs->r2 = FbxFuseErrno2Error(error); 79 | return DOSFALSE; 80 | } 81 | 82 | error = FbxSetAmigaProtectionFlags(fs, fullpath, prot); 83 | if (error && (error != -ENOSYS && error != -EOPNOTSUPP)) { 84 | fs->r2 = FbxFuseErrno2Error(error); 85 | return DOSFALSE; 86 | } 87 | 88 | FbxSetModifyState(fs, 1); 89 | 90 | fs->r2 = 0; 91 | return DOSTRUE; 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/main/FbxInstallTimerCallback.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxInstallTimerCallback ************************** 16 | * 17 | * NAME 18 | * FbxInstallTimerCallback -- Install timer callback. (V53.23) 19 | * 20 | * SYNOPSIS 21 | * struct FbxTimerCallbackData * FbxInstallTimerCallback( 22 | * struct FbxFS * fs, FbxTimerCallbackFunc func, ULONG period); 23 | * 24 | * FUNCTION 25 | * Adds a callback function that will get called as often as specified by 26 | * the period parameter. 27 | * 28 | * INPUTS 29 | * fs - The result of FbxSetupFS(). 30 | * func - Callback function. 31 | * period - Period value in milliseconds. 32 | * 33 | * RESULT 34 | * A pointer to a private data structure that can be passed to 35 | * FbxUninstallTimerCallback() when the callback is no longer 36 | * needed or NULL for failure. 37 | * 38 | * EXAMPLE 39 | * 40 | * NOTES 41 | * 42 | * BUGS 43 | * 44 | * SEE ALSO 45 | * FbxUninstallTimerCallback() 46 | * 47 | * 48 | ***************************************************************************** 49 | * 50 | */ 51 | 52 | #ifdef __AROS__ 53 | AROS_LH3(struct FbxTimerCallbackData *, FbxInstallTimerCallback, 54 | AROS_LHA(struct FbxFS *, fs, A0), 55 | AROS_LHA(FbxTimerCallbackFunc, func, A1), 56 | AROS_LHA(ULONG, period, D0), 57 | struct FileSysBoxBase *, libBase, 13, FileSysBox) 58 | { 59 | AROS_LIBFUNC_INIT 60 | #else 61 | struct FbxTimerCallbackData *FbxInstallTimerCallback( 62 | REG(a0, struct FbxFS *fs), 63 | REG(a1, FbxTimerCallbackFunc func), 64 | REG(d0, ULONG period), 65 | REG(a6, struct FileSysBoxBase *libBase)) 66 | { 67 | #endif 68 | struct FbxTimerCallbackData *cb = NULL; 69 | 70 | ADEBUGF("FbxInstallTimerCallback(%#p, %#p, %lu)\n", fs, func, period); 71 | 72 | if (fs != NULL && func != NULL && period != 0) { 73 | struct Library *SysBase = fs->sysbase; 74 | 75 | cb = AllocFbxTimerCallbackData(fs); 76 | if (cb != NULL) { 77 | cb->lastcall = FbxGetUpTimeMillis(fs); 78 | cb->period = period; 79 | cb->func = func; 80 | 81 | ObtainSemaphore(&fs->fssema); 82 | AddTail((struct List *)&fs->timercallbacklist, (struct Node *)&cb->fschain); 83 | ReleaseSemaphore(&fs->fssema); 84 | } 85 | } 86 | 87 | return cb; 88 | 89 | #ifdef __AROS__ 90 | AROS_LIBFUNC_EXIT 91 | #endif 92 | } 93 | 94 | -------------------------------------------------------------------------------- /src/fsinfodata.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | #ifdef __AROS__ 16 | #define ID_BUSY_DISK AROS_MAKE_ID('B','U','S','Y') 17 | #else 18 | #define ID_BUSY_DISK (0x42555359L) 19 | #endif 20 | 21 | static void FbxFillInfoData(struct FbxFS *fs, struct InfoData *info) { 22 | struct FbxVolume *vol = fs->currvol; 23 | 24 | bzero(info, sizeof(*info)); 25 | 26 | info->id_UnitNumber = fs->fssm ? fs->fssm->fssm_Unit : -1; 27 | 28 | if (OKVOLUME(vol)) { 29 | struct statvfs st; 30 | 31 | bzero(&st, sizeof(st)); 32 | 33 | Fbx_statfs(fs, "/", &st); 34 | 35 | if (vol->writeprotect || (st.f_flag & ST_RDONLY)) 36 | info->id_DiskState = ID_WRITE_PROTECTED; 37 | else 38 | info->id_DiskState = ID_VALIDATED; 39 | 40 | info->id_NumBlocks = st.f_blocks; 41 | info->id_NumBlocksUsed = st.f_blocks - st.f_bfree; 42 | info->id_BytesPerBlock = st.f_frsize; 43 | #ifdef __AROS__ 44 | info->id_DiskType = fs->dostype; 45 | #else 46 | info->id_DiskType = ID_INTER_FFS_DISK; 47 | #endif 48 | info->id_VolumeNode = MKBADDR(vol); 49 | 50 | if (!IsMinListEmpty(&vol->locklist) || 51 | !IsMinListEmpty(&vol->notifylist) || 52 | !IsMinListEmpty(&vol->unres_notifys)) 53 | { 54 | info->id_InUse = DOSTRUE; 55 | } 56 | } 57 | else 58 | { 59 | info->id_DiskState = ID_VALIDATING; 60 | info->id_BytesPerBlock = 512; 61 | 62 | if (BADVOLUME(vol)) 63 | { 64 | //info->id_NumSoftErrors = -1; 65 | info->id_DiskType = ID_NOT_REALLY_DOS; 66 | } 67 | else if (fs->inhibit) 68 | { 69 | info->id_DiskType = ID_BUSY_DISK; 70 | info->id_InUse = DOSTRUE; 71 | } 72 | else 73 | { 74 | info->id_DiskType = ID_NO_DISK_PRESENT; 75 | } 76 | } 77 | } 78 | 79 | int FbxDiskInfo(struct FbxFS *fs, struct InfoData *info) { 80 | PDEBUGF("FbxDiskInfo(%#p, %#p)\n", fs, info); 81 | 82 | FbxFillInfoData(fs, info); 83 | 84 | fs->r2 = 0; 85 | return DOSTRUE; 86 | } 87 | 88 | int FbxInfo(struct FbxFS *fs, struct FbxLock *lock, struct InfoData *info) { 89 | PDEBUGF("FbxInfo(%#p, %#p, %#p)\n", fs, lock, info); 90 | 91 | CHECKVOLUME(DOSFALSE); 92 | 93 | if (lock != NULL) { 94 | CHECKLOCK(lock, DOSFALSE); 95 | 96 | if (lock->fsvol != fs->currvol) { 97 | fs->r2 = ERROR_NO_DISK; 98 | return DOSFALSE; 99 | } 100 | } 101 | 102 | FbxFillInfoData(fs, info); 103 | 104 | fs->r2 = 0; 105 | return DOSTRUE; 106 | } 107 | 108 | -------------------------------------------------------------------------------- /src/strlcpy.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1998 Todd C. Miller 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. The name of the author may not be used to endorse or promote products 14 | * derived from this software without specific prior written permission. 15 | * 16 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 18 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 19 | * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 | * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | */ 27 | 28 | #ifndef __AROS__ 29 | #include "filesysbox_internal.h" 30 | #include 31 | 32 | size_t strlcpy(char *dst, const char *src, size_t siz) { 33 | register char *d = dst; 34 | register const char *s = src; 35 | register size_t n = siz; 36 | 37 | /* Copy as many bytes as will fit */ 38 | if (n != 0 && --n != 0) { 39 | do { 40 | if ((*d++ = *s++) == 0) 41 | break; 42 | } while (--n != 0); 43 | } 44 | 45 | /* Not enough room in dst, add NUL and traverse rest of src */ 46 | if (n == 0) { 47 | if (siz != 0) 48 | *d = '\0'; /* NUL-terminate dst */ 49 | while (*s++) 50 | ; 51 | } 52 | 53 | return s - src - 1; /* count does not include NUL */ 54 | } 55 | 56 | size_t strlcat(char *dst, const char *src, size_t siz) { 57 | register char *d = dst; 58 | register const char *s = src; 59 | register size_t n = siz; 60 | size_t dlen; 61 | 62 | /* Find the end of dst and adjust bytes left but don't go past end */ 63 | while (n-- != 0 && *d != '\0') 64 | d++; 65 | dlen = d - dst; 66 | n = siz - dlen; 67 | 68 | if (n == 0) 69 | return dlen + strlen(s); 70 | while (*s != '\0') { 71 | if (n != 1) { 72 | *d++ = *s; 73 | n--; 74 | } 75 | s++; 76 | } 77 | *d = '\0'; 78 | 79 | return dlen + (s - src); /* count does not include NUL */ 80 | } 81 | #endif /* !__AROS__ */ 82 | 83 | -------------------------------------------------------------------------------- /src/fsdelete.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | static int Fbx_unlink(struct FbxFS *fs, const char *path) 16 | { 17 | ODEBUGF("Fbx_unlink(%#p, '%s')\n", fs, path); 18 | 19 | return FSOP unlink(path, &fs->fcntx); 20 | } 21 | 22 | static int Fbx_rmdir(struct FbxFS *fs, const char *path) 23 | { 24 | ODEBUGF("Fbx_rmdir(%#p, '%s')\n", fs, path); 25 | 26 | return FSOP rmdir(path, &fs->fcntx); 27 | } 28 | 29 | int FbxDeleteObject(struct FbxFS *fs, struct FbxLock *lock, const char *name) { 30 | struct FbxEntry *e; 31 | int error; 32 | struct fbx_stat statbuf; 33 | char fullpath[FBX_MAX_PATH]; 34 | #ifdef ENABLE_CHARSET_CONVERSION 35 | char fsname[FBX_MAX_NAME]; 36 | #endif 37 | 38 | PDEBUGF("FbxDeleteObject(%#p, %#p, '%s')\n", fs, lock, name); 39 | 40 | CHECKVOLUME(DOSFALSE); 41 | CHECKWRITABLE(DOSFALSE); 42 | 43 | if (lock != NULL) { 44 | CHECKLOCK(lock, DOSFALSE); 45 | 46 | if (lock->fsvol != fs->currvol) { 47 | fs->r2 = ERROR_NO_DISK; 48 | return DOSFALSE; 49 | } 50 | } 51 | 52 | #ifdef ENABLE_CHARSET_CONVERSION 53 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 54 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 55 | fs->r2 = ERROR_LINE_TOO_LONG; 56 | return DOSFALSE; 57 | } 58 | name = fsname; 59 | } 60 | #else 61 | CHECKSTRING(name, DOSFALSE); 62 | #endif 63 | 64 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 65 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 66 | return DOSFALSE; 67 | } 68 | 69 | if (IsRoot(fullpath)) { 70 | // can't delete root 71 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 72 | return DOSFALSE; 73 | } 74 | 75 | e = FbxFindEntry(fs, fullpath); 76 | if (e != NULL && !IsMinListEmpty(&e->locklist)) { 77 | // we cannot delete if there are locks 78 | fs->r2 = ERROR_OBJECT_IN_USE; 79 | return DOSFALSE; 80 | } 81 | 82 | error = Fbx_getattr(fs, fullpath, &statbuf); 83 | if (error) { 84 | fs->r2 = FbxFuseErrno2Error(error); 85 | return DOSFALSE; 86 | } 87 | 88 | if (S_ISDIR(statbuf.st_mode)) { 89 | error = Fbx_rmdir(fs, fullpath); 90 | } else { 91 | error = Fbx_unlink(fs, fullpath); 92 | } 93 | if (error) { 94 | fs->r2 = FbxFuseErrno2Error(error); 95 | return DOSFALSE; 96 | } 97 | 98 | if (e != NULL) { 99 | FbxUnResolveNotifys(fs, e); 100 | FbxCleanupEntry(fs, e); 101 | } 102 | 103 | while (FbxParentPath(fs, fullpath)) { 104 | e = FbxFindEntry(fs, fullpath); 105 | if (e != NULL) FbxDoNotifyEntry(fs, e); 106 | } 107 | 108 | FbxSetModifyState(fs, 1); 109 | 110 | fs->r2 = 0; 111 | return DOSTRUE; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/fssetfilesize.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_ftruncate(struct FbxFS *fs, const char *path, QUAD size, struct fuse_file_info *fi) 14 | { 15 | ODEBUGF("Fbx_ftruncate(%#p, '%s', %lld, %#p)\n", fs, path, size, fi); 16 | 17 | return FSOP ftruncate(path, size, fi, &fs->fcntx); 18 | } 19 | 20 | static QUAD FbxTruncNewSize(struct FbxFS *fs, struct FbxLock *lock, QUAD newsize) { 21 | struct FbxLock *fslock; 22 | struct MinNode *chain, *succ; 23 | 24 | PDEBUGF("FbxTruncNewSize(%#p, %#p, %lld)\n", fs, lock, newsize); 25 | 26 | chain = lock->entry->locklist.mlh_Head; 27 | while ((succ = chain->mln_Succ) != NULL) { 28 | fslock = FSLOCKFROMENTRYCHAIN(chain); 29 | if (fslock != lock && fslock->filepos > newsize) { 30 | newsize = fslock->filepos; 31 | } 32 | chain = succ; 33 | } 34 | 35 | return newsize; 36 | } 37 | 38 | QUAD FbxSetFileSize64(struct FbxFS *fs, struct FbxLock *lock, QUAD offs, int mode) { 39 | QUAD oldsize, newsize; 40 | int error; 41 | 42 | PDEBUGF("FbxSetFileSize(%#p, %#p, %lld, %d)\n", fs, lock, offs, mode); 43 | 44 | oldsize = FbxGetFileSize(fs, lock); 45 | if (oldsize == -1) return -1; 46 | 47 | switch (mode) { 48 | case OFFSET_BEGINNING: 49 | newsize = offs; 50 | break; 51 | case OFFSET_CURRENT: 52 | newsize = lock->filepos + offs; 53 | break; 54 | case OFFSET_END: 55 | newsize = oldsize + offs; 56 | break; 57 | default: 58 | fs->r2 = ERROR_SEEK_ERROR; 59 | return -1; 60 | } 61 | 62 | if (newsize == oldsize) { 63 | fs->r2 = 0; 64 | return oldsize; 65 | } 66 | 67 | CHECKWRITABLE(-1); 68 | 69 | /* check if there are other locks to this file and 70 | * if any of their positions are above newsize. */ 71 | if (FbxTruncNewSize(fs, lock, newsize) > newsize) { 72 | fs->r2 = ERROR_OBJECT_IN_USE; 73 | return -1; 74 | } 75 | 76 | /* check if our lock's position points beyond new filesize 77 | * if so, truncate position to new filesize.. */ 78 | if (lock->filepos > newsize) lock->filepos = newsize; 79 | 80 | error = Fbx_ftruncate(fs, lock->entry->path, newsize, lock->info); 81 | if (error) { 82 | fs->r2 = FbxFuseErrno2Error(error); 83 | return -1; 84 | } 85 | 86 | lock->flags |= LOCKFLAG_MODIFIED; /* for notification */ 87 | FbxSetModifyState(fs, 1); 88 | 89 | fs->r2 = 0; 90 | return newsize; 91 | } 92 | 93 | SIPTR FbxSetFileSize(struct FbxFS *fs, struct FbxLock *lock, SIPTR offs, int mode) { 94 | QUAD newsize; 95 | 96 | newsize = FbxSetFileSize64(fs, lock, offs, mode); 97 | if (newsize != (SIPTR)newsize) { 98 | fs->r2 = ERROR_OBJECT_TOO_LARGE; 99 | return -1; 100 | } 101 | 102 | return (SIPTR)newsize; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/fssetdate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | static int Fbx_utimens(struct FbxFS *fs, const char *path, const struct timespec *tv) 14 | { 15 | ODEBUGF("Fbx_utimens(%#p, '%s', %#p)\n", fs, path, tv); 16 | 17 | return FSOP utimens(path, tv, &fs->fcntx); 18 | } 19 | 20 | static int Fbx_utime(struct FbxFS *fs, const char *path, struct utimbuf *ubuf) 21 | { 22 | ODEBUGF("Fbx_utime(%#p, '%s', %#p)\n", fs, path, ubuf); 23 | 24 | return FSOP utime(path, ubuf, &fs->fcntx); 25 | } 26 | 27 | static void FbxDS2TimeSpec(struct FbxFS *fs, const struct DateStamp *ds, 28 | struct timespec *ts) 29 | { 30 | ULONG sec, nsec; 31 | 32 | sec = ds->ds_Days * (60*60*24); 33 | sec += ds->ds_Minute * 60; 34 | sec += ds->ds_Tick / TICKS_PER_SECOND; 35 | nsec = (ds->ds_Tick % TICKS_PER_SECOND) * ((1000*1000*1000) / TICKS_PER_SECOND); 36 | 37 | // add 8 years of seconds to adjust for different epoch. 38 | sec += UNIXTIMEOFFSET; 39 | 40 | /* convert to GMT */ 41 | sec += fs->gmtoffset * 60; 42 | 43 | ts->tv_sec = sec; 44 | ts->tv_nsec = nsec; 45 | } 46 | 47 | int FbxSetDate(struct FbxFS *fs, struct FbxLock *lock, const char *name, 48 | const struct DateStamp *date) 49 | { 50 | struct timespec tv[2]; 51 | int error; 52 | char fullpath[FBX_MAX_PATH]; 53 | #ifdef ENABLE_CHARSET_CONVERSION 54 | char fsname[FBX_MAX_NAME]; 55 | #endif 56 | 57 | PDEBUGF("FbxSetDate(%#p, %#p, '%s', %#p)\n", fs, lock, name, date); 58 | 59 | CHECKVOLUME(DOSFALSE); 60 | CHECKWRITABLE(DOSFALSE); 61 | 62 | if (lock != NULL) { 63 | CHECKLOCK(lock, DOSFALSE); 64 | 65 | if (lock->fsvol != fs->currvol) { 66 | fs->r2 = ERROR_NO_DISK; 67 | return DOSFALSE; 68 | } 69 | } 70 | 71 | #ifdef ENABLE_CHARSET_CONVERSION 72 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 73 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 74 | fs->r2 = ERROR_LINE_TOO_LONG; 75 | return DOSFALSE; 76 | } 77 | name = fsname; 78 | } 79 | #else 80 | CHECKSTRING(name, DOSFALSE); 81 | #endif 82 | 83 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 84 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 85 | return DOSFALSE; 86 | } 87 | 88 | FbxDS2TimeSpec(fs, date, &tv[0]); 89 | tv[1] = tv[0]; 90 | 91 | if (FSOP utimens) { 92 | error = Fbx_utimens(fs, fullpath, tv); 93 | } else { 94 | struct utimbuf ubuf; 95 | 96 | ubuf.actime = tv[0].tv_sec; 97 | ubuf.modtime = tv[1].tv_sec; 98 | 99 | error = Fbx_utime(fs, fullpath, &ubuf); 100 | } 101 | if (error) { 102 | fs->r2 = FbxFuseErrno2Error(error); 103 | return DOSFALSE; 104 | } 105 | 106 | FbxDoNotify(fs, fullpath); 107 | 108 | FbxSetModifyState(fs, 1); 109 | 110 | fs->r2 = 0; 111 | return DOSTRUE; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /src/timer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #include "filesysbox_internal.h" 9 | 10 | struct timerequest *FbxSetupTimerIO(struct FbxFS *fs) { 11 | struct Library *SysBase = fs->sysbase; 12 | struct MsgPort *mp; 13 | struct timerequest *tr; 14 | 15 | DEBUGF("FbxSetupTimerIO(%#p)\n", fs); 16 | 17 | mp = CreateMsgPort(); 18 | tr = CreateIORequest(mp, sizeof(*tr)); 19 | if (tr == NULL) { 20 | DeleteMsgPort(mp); 21 | return NULL; 22 | } 23 | 24 | if (OpenDevice((CONST_STRPTR)"timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0) != 0) { 25 | DeleteIORequest(tr); 26 | DeleteMsgPort(mp); 27 | return NULL; 28 | } 29 | 30 | fs->timerio = tr; 31 | fs->timerbase = tr->tr_node.io_Device; 32 | fs->timerbusy = FALSE; 33 | 34 | return tr; 35 | } 36 | 37 | void FbxCleanupTimerIO(struct FbxFS *fs) { 38 | DEBUGF("FbxCleanupTimerIO(%#p)\n", fs); 39 | 40 | if (fs->timerbase != NULL) { 41 | struct Library *SysBase = fs->sysbase; 42 | struct timerequest *tr = fs->timerio; 43 | struct MsgPort *mp = tr->tr_node.io_Message.mn_ReplyPort; 44 | 45 | CloseDevice((struct IORequest *)tr); 46 | DeleteIORequest(tr); 47 | DeleteMsgPort(mp); 48 | } 49 | } 50 | 51 | void FbxInitUpTime(struct FbxFS *fs) { 52 | struct Device *TimerBase = fs->timerbase; 53 | struct EClockVal ev; 54 | 55 | ReadEClock(&ev); 56 | fs->eclock_initial = ((UQUAD)ev.ev_hi << 32)|((UQUAD)ev.ev_lo); 57 | } 58 | 59 | void _FbxGetUpTime(struct FbxFS *fs, struct timeval *tv) { 60 | struct Device *TimerBase = fs->timerbase; 61 | struct EClockVal ev; 62 | UQUAD eclock_current; 63 | UQUAD eclock_elapsed; 64 | ULONG freq, seconds, remainder, micros; 65 | 66 | freq = ReadEClock(&ev); 67 | eclock_current = ((UQUAD)ev.ev_hi << 32)|((UQUAD)ev.ev_lo); 68 | eclock_elapsed = eclock_current - fs->eclock_initial; 69 | 70 | #ifdef __mc68020 71 | ULONG dummy; 72 | __asm__("divul %4,%0:%1" 73 | : "=d" (remainder), "=d" (seconds) 74 | : "0" ((ULONG)(eclock_elapsed >> 32)), "1" ((ULONG)eclock_elapsed), "d" (freq) 75 | : "cc" 76 | ); 77 | __asm__("mulul #1000000,%1:%0\n" 78 | "\tdivul %3,%1:%0" 79 | : "=&d" (micros), "=&d" (dummy) 80 | : "0" (remainder), "d" (freq) 81 | : "cc" 82 | ); 83 | #else 84 | seconds = eclock_elapsed / freq; 85 | remainder = eclock_elapsed % freq; 86 | micros = ((UQUAD)remainder * 1000000ULL) / freq; 87 | #endif 88 | tv->tv_secs = seconds; 89 | tv->tv_micro = micros; 90 | } 91 | 92 | ULONG FbxGetUpTimeMillis(struct FbxFS *fs) { 93 | struct timeval tv; 94 | 95 | _FbxGetUpTime(fs, &tv); 96 | #if defined(__mc68020) || defined(__mc68060) 97 | ULONG result; 98 | __asm__("mulul #1000,%0\n" 99 | "divuw #1000,%2\n" 100 | "extl %2\n" 101 | "addl %2,%0" 102 | : "=&d" (result) 103 | : "0" (tv.tv_secs), "d" (tv.tv_micro) 104 | : "2", "cc" 105 | ); 106 | return result; 107 | #else 108 | return (ULONG)tv.tv_secs * 1000UL + (ULONG)tv.tv_micro / 1000UL; 109 | #endif 110 | } 111 | 112 | -------------------------------------------------------------------------------- /src/fsaddnotify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | int FbxAddNotify(struct FbxFS *fs, struct NotifyRequest *notify) { 16 | struct Library *SysBase = fs->sysbase; 17 | struct fbx_stat statbuf; 18 | struct FbxEntry *e; 19 | struct FbxNotifyNode *nn; 20 | LONG etype; 21 | int error; 22 | const char *fullname; 23 | char fullpath[FBX_MAX_PATH]; 24 | #ifdef ENABLE_CHARSET_CONVERSION 25 | char fsfullname[FBX_MAX_PATH]; 26 | #endif 27 | 28 | PDEBUGF("FbxAddNotify(%#p, %#p)\n", fs, notify); 29 | 30 | CHECKVOLUME(DOSFALSE); 31 | 32 | notify->nr_notifynode = (IPTR)NULL; 33 | notify->nr_MsgCount = 0; 34 | 35 | fullname = (const char *)notify->nr_FullName; 36 | #ifdef ENABLE_CHARSET_CONVERSION 37 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 38 | if (FbxLocalToUTF8(fs, fsfullname, fullname, FBX_MAX_PATH) >= FBX_MAX_PATH) { 39 | fs->r2 = ERROR_LINE_TOO_LONG; 40 | return DOSFALSE; 41 | } 42 | fullname = fsfullname; 43 | } 44 | #else 45 | CHECKSTRING(fullname, DOSFALSE); 46 | #endif 47 | 48 | if (!FbxLockName2Path(fs, NULL, fullname, fullpath)) { 49 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 50 | return DOSFALSE; 51 | } 52 | 53 | error = Fbx_getattr(fs, fullpath, &statbuf); 54 | if (error) { 55 | if (fs->r2 == -ENOENT) { // file did not exist 56 | NDEBUGF("FbxAddNotify: file '%s' did not exist.\n", fullpath); 57 | 58 | nn = AllocFbxNotifyNode(); 59 | if (nn == NULL) { 60 | fs->r2 = ERROR_NO_FREE_STORE; 61 | return DOSFALSE; 62 | } 63 | 64 | nn->nr = notify; 65 | nn->entry = NULL; 66 | 67 | notify->nr_notifynode = (IPTR)nn; 68 | // lets put request on the unresolved list 69 | AddTail((struct List *)&fs->currvol->unres_notifys, (struct Node *)&nn->chain); 70 | } else { 71 | NDEBUGF("FbxAddNotify: getattr() error %d.\n", error); 72 | fs->r2 = FbxFuseErrno2Error(error); 73 | return DOSFALSE; 74 | } 75 | } else { // file existed 76 | NDEBUGF("FbxAddNotify: file '%s' existed.\n", fullpath); 77 | 78 | if (S_ISREG(statbuf.st_mode)) { 79 | etype = ETYPE_FILE; 80 | } else { 81 | etype = ETYPE_DIR; 82 | } 83 | 84 | e = FbxFindEntry(fs, fullpath); 85 | if (e == NULL) { 86 | e = FbxSetupEntry(fs, fullpath, etype, statbuf.st_ino); 87 | if (e == NULL) return DOSFALSE; 88 | } 89 | 90 | nn = AllocFbxNotifyNode(); 91 | if (nn == NULL) { 92 | fs->r2 = ERROR_NO_FREE_STORE; 93 | return DOSFALSE; 94 | } 95 | 96 | nn->nr = notify; 97 | nn->entry = e; 98 | 99 | notify->nr_notifynode = (IPTR)nn; 100 | AddTail((struct List *)&e->notifylist, (struct Node *)&nn->chain); 101 | 102 | if (notify->nr_Flags & NRF_NOTIFY_INITIAL) { 103 | FbxDoNotifyRequest(fs, notify); 104 | } 105 | } 106 | 107 | notify->nr_Handler = fs->fsport; 108 | 109 | AddTail((struct List *)&fs->currvol->notifylist, (struct Node *)&nn->volumechain); 110 | 111 | fs->r2 = 0; 112 | return DOSTRUE; 113 | } 114 | 115 | -------------------------------------------------------------------------------- /src/main/FbxQueryMountMsg.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | /****** filesysbox.library/FbxQueryMountMsg ********************************* 16 | * 17 | * NAME 18 | * FbxQueryMountMsg -- Get information from mount message 19 | * 20 | * SYNOPSIS 21 | * APTR FbxQueryMountMsg(struct Message *msg, LONG attr); 22 | * 23 | * FUNCTION 24 | * Returns information from a mount message (normally 25 | * the first message passed to a filesystems port). 26 | * 27 | * The following attributes can be queried: 28 | * 29 | * FBXQMM_MOUNT_NAME (STRPTR) 30 | * Device name ("DH3", "USB1"). 31 | * 32 | * FBXQMM_MOUNT_CONTROL (STRPTR) 33 | * Control string if specified during mount. 34 | * 35 | * FBXQMM_FSSM (struct FileSysStartupMsg *) 36 | * File system startup message. 37 | * 38 | * FBXQMM_ENVIRON (struct DosEnvec *) 39 | * Disk environment structure. 40 | * 41 | * INPUTS 42 | * msg - mount message 43 | * attr - attribute number 44 | * 45 | * RESULT 46 | * The attributes value. If value is pointer to something, 47 | * do not assume it will be valid after mount message has 48 | * been returned. 49 | * 50 | * EXAMPLE 51 | * 52 | * NOTES 53 | * 54 | * BUGS 55 | * 56 | * SEE ALSO 57 | * 58 | ***************************************************************************** 59 | * 60 | */ 61 | 62 | #ifdef __AROS__ 63 | AROS_LH2(APTR, FbxQueryMountMsg, 64 | AROS_LHA(struct Message *, msg, A0), 65 | AROS_LHA(LONG, attr, D0), 66 | struct FileSysBoxBase *, libBase, 5, FileSysBox) 67 | { 68 | AROS_LIBFUNC_INIT 69 | #else 70 | APTR FbxQueryMountMsg( 71 | REG(a0, struct Message *msg), 72 | REG(d0, LONG attr), 73 | REG(a6, struct FileSysBoxBase *libBase)) 74 | { 75 | #endif 76 | ADEBUGF("FbxQueryMountMsg(%#p, %ld)\n", msg, attr); 77 | 78 | struct DosPacket *pkt = (struct DosPacket *)msg->mn_Node.ln_Name; 79 | struct DeviceNode *devnode = BADDR(pkt->dp_Arg3); 80 | struct FileSysStartupMsg *fssm; 81 | struct DosEnvec *de; 82 | 83 | switch (attr) { 84 | case FBXQMM_MOUNT_NAME: 85 | #ifdef __AROS__ 86 | return AROS_BSTR_ADDR(devnode->dn_Name); 87 | #else 88 | return BADDR(devnode->dn_Name) + 1; 89 | #endif 90 | case FBXQMM_MOUNT_CONTROL: 91 | fssm = FbxGetFSSM(libBase->sysbase, devnode); 92 | if (fssm != NULL) { 93 | de = BADDR(fssm->fssm_Environ); 94 | if (IS_VALID_BPTR(de->de_Control) && de->de_Control > 4095) 95 | #ifdef __AROS__ 96 | return AROS_BSTR_ADDR(de->de_Control); 97 | #else 98 | return BADDR(de->de_Control) + 1; 99 | #endif 100 | } 101 | return NULL; 102 | case FBXQMM_FSSM: 103 | fssm = FbxGetFSSM(libBase->sysbase, devnode); 104 | return fssm; 105 | case FBXQMM_ENVIRON: 106 | fssm = FbxGetFSSM(libBase->sysbase, devnode); 107 | if (fssm != NULL) { 108 | return BADDR(fssm->fssm_Environ); 109 | } 110 | default: 111 | return NULL; 112 | } 113 | 114 | #ifdef __AROS__ 115 | AROS_LIBFUNC_EXIT 116 | #endif 117 | } 118 | 119 | -------------------------------------------------------------------------------- /src/main/FbxCleanupFS.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | #include 15 | 16 | /****** filesysbox.library/FbxCleanupFS ************************************* 17 | * 18 | * NAME 19 | * FbxCleanupFS -- Delete a filesystem handle 20 | * 21 | * SYNOPSIS 22 | * void FbxCleanupFS(struct FbxFS *fs); 23 | * 24 | * FUNCTION 25 | * Cleans up any resources managed by the filesystem handle and 26 | * frees the handle itself. 27 | * 28 | * INPUTS 29 | * fs - filesystem handle. 30 | * 31 | * RESULT 32 | * This function does not return a result. 33 | * 34 | * EXAMPLE 35 | * 36 | * NOTES 37 | * Passing a NULL pointer as fs is safe and will do nothing. 38 | * 39 | * BUGS 40 | * 41 | * SEE ALSO 42 | * FbxSetupFS() 43 | * 44 | ***************************************************************************** 45 | * 46 | */ 47 | 48 | #ifdef __AROS__ 49 | AROS_LH1(void, FbxCleanupFS, 50 | AROS_LHA(struct FbxFS *, fs, A0), 51 | struct FileSysBoxBase *, libBase, 8, FileSysBox) 52 | { 53 | AROS_LIBFUNC_INIT 54 | #else 55 | void FbxCleanupFS( 56 | REG(a0, struct FbxFS * fs), 57 | REG(a6, struct FileSysBoxBase *libBase)) 58 | { 59 | #endif 60 | ADEBUGF("FbxCleanupFS(%#p)\n", fs); 61 | 62 | if (fs != NULL) { 63 | struct Library *SysBase = fs->sysbase; 64 | struct MinNode *chain; 65 | 66 | // clear msgport in device node. 67 | if (fs->devnode != NULL) { 68 | fs->devnode->dn_Task = NULL; 69 | fs->devnode = NULL; 70 | } 71 | 72 | // doslist process 73 | if (fs->dlproc_port != NULL) { 74 | ObtainSemaphore(&libBase->procsema); 75 | if (--libBase->dlproc_refcount == 0) 76 | Signal(&libBase->dlproc->pr_Task, SIGBREAKF_CTRL_C); 77 | ReleaseSemaphore(&libBase->procsema); 78 | } 79 | 80 | // lockhandler process 81 | if (fs->lhproc_port != NULL) { 82 | ObtainSemaphore(&libBase->procsema); 83 | if (--libBase->lhproc_refcount == 0) 84 | Signal(&libBase->lhproc->pr_Task, SIGBREAKF_CTRL_C); 85 | ReleaseSemaphore(&libBase->procsema); 86 | } 87 | 88 | while ((chain = (struct MinNode *)RemHead((struct List *)&fs->timercallbacklist)) != NULL) { 89 | FreeFbxTimerCallbackData(fs, FSTIMERCALLBACKDATAFROMFSCHAIN(chain)); 90 | } 91 | 92 | if (fs->fsflags & FBXF_ENABLE_DISK_CHANGE_DETECTION) { 93 | FbxRemDiskChangeHandler(fs); 94 | } 95 | 96 | #ifdef ENABLE_CHARSET_CONVERSION 97 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 98 | if (fs->avlbuf != NULL) 99 | FreeMem(fs->avlbuf, 128*sizeof(struct FbxAVL)); 100 | 101 | if (fs->maptable != NULL) 102 | FreeMem(fs->maptable, 256*sizeof(FbxUCS)); 103 | } 104 | #endif 105 | 106 | DeleteMsgPort(fs->fsport); 107 | DeleteMsgPort(fs->notifyreplyport); 108 | 109 | FreeSignal(fs->diskchangesig); 110 | #ifndef NODEBUG 111 | FreeSignal(fs->dbgflagssig); 112 | #endif 113 | 114 | DeletePool(fs->mempool); 115 | 116 | FbxCleanupTimerIO(fs); 117 | 118 | bzero(fs, sizeof(*fs)); 119 | 120 | FreeFbxFS(fs); 121 | } 122 | 123 | ADEBUGF("FbxCleanupFS: DONE\n"); 124 | 125 | #ifdef __AROS__ 126 | AROS_LIBFUNC_EXIT 127 | #endif 128 | } 129 | 130 | -------------------------------------------------------------------------------- /mkrelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Script for generating a release archive. 4 | # 5 | 6 | HOST="${1:-i386-aros}" 7 | FORMAT="${2:-lha}" 8 | 9 | #make HOST=$HOST clean 10 | make HOST=$HOST all autodoc 11 | 12 | if [ "$HOST" = "m68k-amigaos" ]; then 13 | chmod 775 bin/filesysbox.library.000 14 | chmod 775 bin/filesysbox.library.020 15 | chmod 775 bin/filesysbox.library.060 16 | else 17 | CPU=`echo "${HOST}" | cut -d'-' -f1` 18 | chmod 775 bin/filesysbox.library.${CPU} 19 | fi; 20 | 21 | DESTDIR='tmp' 22 | #FULLVERS=`version bin/filesysbox.library` 23 | #NUMVERS=`echo "${FULLVERS}" | cut -d' ' -f2` 24 | 25 | rm -rf ${DESTDIR} 26 | mkdir -p ${DESTDIR}/filesysbox/Libs 27 | mkdir -p ${DESTDIR}/filesysbox/Developer/AutoDocs 28 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/sfd 29 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/fd 30 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/include_h/clib 31 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/include_h/defines 32 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/include_h/inline 33 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/include_h/libraries 34 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/include_h/proto 35 | mkdir -p ${DESTDIR}/filesysbox/Developer/include/include_h/sys 36 | 37 | cp -p README ${DESTDIR}/filesysbox 38 | cp -p LICENSE.APL ${DESTDIR}/filesysbox 39 | cp -p releasenotes ${DESTDIR}/filesysbox 40 | if [ "$HOST" = "m68k-amigaos" ]; then 41 | cp -p Install ${DESTDIR}/filesysbox 42 | cp -p bin/filesysbox.library.000 ${DESTDIR}/filesysbox/Libs 43 | cp -p bin/filesysbox.library.020 ${DESTDIR}/filesysbox/Libs 44 | cp -p bin/filesysbox.library.060 ${DESTDIR}/filesysbox/Libs 45 | else 46 | cp -p Install-AROS ${DESTDIR}/filesysbox/Install 47 | cp -p bin/filesysbox.library.${CPU} ${DESTDIR}/filesysbox/Libs/filesysbox.library 48 | fi; 49 | cp -p filesysbox.doc ${DESTDIR}/filesysbox/Developer/AutoDocs 50 | cp -p filesysbox_lib.sfd ${DESTDIR}/filesysbox/Developer/include/sfd 51 | cp -p include/fd/filesysbox_lib.fd ${DESTDIR}/filesysbox/Developer/include/fd 52 | cp -p include/clib/filesysbox_protos.h ${DESTDIR}/filesysbox/Developer/include/include_h/clib 53 | cp -p include/defines/filesysbox.h ${DESTDIR}/filesysbox/Developer/include/include_h/defines 54 | cp -p include/inline/filesysbox.h ${DESTDIR}/filesysbox/Developer/include/include_h/inline 55 | cp -p include/libraries/filesysbox.h ${DESTDIR}/filesysbox/Developer/include/include_h/libraries 56 | cp -p include/proto/filesysbox.h ${DESTDIR}/filesysbox/Developer/include/include_h/proto 57 | cp -p include/sys/statvfs.h ${DESTDIR}/filesysbox/Developer/include/include_h/sys 58 | 59 | cp -p icons/def_drawer.info ${DESTDIR}/filesysbox.info 60 | cp -p icons/def_doc.info ${DESTDIR}/filesysbox/README.info 61 | cp -p icons/def_doc.info ${DESTDIR}/filesysbox/LICENSE.APL.info 62 | cp -p icons/def_doc.info ${DESTDIR}/filesysbox/releasenotes.info 63 | cp -p icons/def_install.info ${DESTDIR}/filesysbox/Install.info 64 | 65 | case "${FORMAT}" in 66 | "7z") 67 | rm -f filesysbox.${HOST}.7z 68 | 7za u filesysbox.${HOST}.7z ./${DESTDIR}/* 69 | echo "filesysbox.${HOST}.7z created" 70 | ;; 71 | "iso") 72 | rm -f filesysbox.${HOST}.iso 73 | PREVDIR=`pwd` 74 | cd ${DESTDIR} && mkisofs -R -o ../filesysbox.${HOST}.iso -V FILESYSBOX . 75 | cd ${PREVDIR} 76 | echo "filesysbox.${HOST}.iso created" 77 | ;; 78 | "lha") 79 | rm -rf filesysbox.${HOST}.lha 80 | PREVDIR=`pwd` 81 | cd ${DESTDIR} && lha ao5 ../filesysbox.${HOST}.lha * 82 | cd ${PREVDIR} 83 | echo "filesysbox.${HOST}.lha created" 84 | ;; 85 | esac 86 | 87 | rm -rf ${DESTDIR} 88 | 89 | -------------------------------------------------------------------------------- /dismount/dismount.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Dismount command for use with filesysbox clients. 3 | * 4 | * Copyright (c) 2013-2025 Fredrik Wikstrom 5 | * 6 | * This code is released under AROS PUBLIC LICENSE 1.1 7 | * See the file LICENSE.APL 8 | */ 9 | 10 | #include "FbxDismount_rev.h" 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | #include 21 | 22 | #ifndef __AROS__ 23 | typedef ULONG IPTR; 24 | typedef LONG SIPTR; 25 | #endif 26 | 27 | #define TEMPLATE "DEVICE/A" 28 | enum { 29 | ARG_DEVICE, 30 | NUM_ARGS 31 | }; 32 | 33 | static TEXT dosName[]; 34 | static TEXT template[]; 35 | static TEXT progName[]; 36 | static TEXT pktName[]; 37 | 38 | #ifdef __AROS__ 39 | AROS_UFH3(int, _start, 40 | AROS_UFHA(STRPTR, argstr, A0), 41 | AROS_UFHA(ULONG, arglen, D0), 42 | AROS_UFHA(struct Library *, SysBase, A6) 43 | ) 44 | { 45 | AROS_USERFUNC_INIT 46 | #else 47 | int _start(void) 48 | { 49 | struct Library *SysBase = *(struct Library **)4; 50 | #endif 51 | struct Process *me = (struct Process *)FindTask(NULL); 52 | struct Library *DOSBase; 53 | struct RDArgs *rda; 54 | SIPTR args[NUM_ARGS]; 55 | TEXT devname[256]; 56 | struct DosPacket *pkt = NULL; 57 | struct DosList *dol; 58 | struct DeviceNode *dn; 59 | BOOL pktsent = FALSE; 60 | LONG error; 61 | int rc = RETURN_ERROR; 62 | 63 | DOSBase = OpenLibrary(dosName, 39); 64 | if (DOSBase == NULL) 65 | { 66 | Alert(AG_OpenLib | AO_DOSLib); 67 | return RETURN_FAIL; 68 | } 69 | 70 | bzero(args, sizeof(args)); 71 | rda = ReadArgs(template, (APTR)args, NULL); 72 | if (rda == NULL) 73 | { 74 | PrintFault(error = IoErr(), progName); 75 | goto cleanup; 76 | } 77 | 78 | SplitName((CONST_STRPTR)args[ARG_DEVICE], ':', devname, 0, sizeof(devname)); 79 | 80 | pkt = AllocDosObject(DOS_STDPKT, NULL); 81 | if (pkt == NULL) 82 | { 83 | PrintFault(error = ERROR_NO_FREE_STORE, progName); 84 | goto cleanup; 85 | } 86 | 87 | dol = LockDosList(LDF_DEVICES | LDF_READ); 88 | dn = (struct DeviceNode *)FindDosEntry(dol, devname, LDF_DEVICES | LDF_READ); 89 | if (dn != NULL && dn->dn_Task != NULL) 90 | { 91 | pkt->dp_Type = ACTION_DIE; 92 | SendPkt(pkt, dn->dn_Task, &me->pr_MsgPort); 93 | pktsent = TRUE; 94 | } 95 | UnLockDosList(LDF_DEVICES | LDF_READ); 96 | 97 | if (dn == NULL) 98 | { 99 | PrintFault(error = ERROR_OBJECT_NOT_FOUND, devname); 100 | goto cleanup; 101 | } 102 | 103 | if (pktsent) 104 | { 105 | WaitPkt(); 106 | if (pkt->dp_Res1 == DOSFALSE) 107 | { 108 | PrintFault(error = pkt->dp_Res2, pktName); 109 | goto cleanup; 110 | } 111 | } 112 | 113 | dol = LockDosList(LDF_DEVICES | LDF_WRITE); 114 | dn = (struct DeviceNode *)FindDosEntry(dol, devname, LDF_DEVICES | LDF_WRITE); 115 | if (dn != NULL) 116 | { 117 | RemDosEntry((struct DosList *)dn); 118 | } 119 | UnLockDosList(LDF_DEVICES | LDF_WRITE); 120 | 121 | rc = RETURN_OK; 122 | 123 | cleanup: 124 | if (pkt != NULL) FreeDosObject(DOS_STDPKT, pkt); 125 | if (rda != NULL) FreeArgs(rda); 126 | 127 | if (rc != RETURN_OK && error != 0) 128 | { 129 | SetIoErr(error); 130 | } 131 | 132 | CloseLibrary(DOSBase); 133 | 134 | return rc; 135 | 136 | #ifdef __AROS__ 137 | AROS_USERFUNC_EXIT 138 | #endif 139 | } 140 | 141 | static TEXT USED verstag[] = VERSTAG; 142 | static TEXT dosName[] = "dos.library"; 143 | static TEXT template[] = TEMPLATE; 144 | static TEXT progName[] = "FbxDismount"; 145 | static TEXT pktName[] = "ACTION_DIE"; 146 | 147 | -------------------------------------------------------------------------------- /src/main/FbxQueryFS.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include 12 | #include "filesysbox_vectors.h" 13 | #include "filesysbox_internal.h" 14 | 15 | #include 16 | 17 | /****** filesysbox.library/FbxQueryFS *************************************** 18 | * 19 | * NAME 20 | * FbxQueryFS -- Query function for FS 21 | * FbxQueryFSTags -- Vararg stub 22 | * 23 | * SYNOPSIS 24 | * void FbxQueryFS(struct FbxFS * fs, const struct TagItem * tags); 25 | * void FbxQueryFSTags(struct FbxFS * fs, ...); 26 | * 27 | * FUNCTION 28 | * Function for reading filesystem attributes. 29 | * 30 | * INPUTS 31 | * fs - The result of FbxSetupFS(). 32 | * tags - Tags to query. 33 | * 34 | * TAGS 35 | * FBXT_FSFLAGS (ULONG) 36 | * Filesystem flags. 37 | * 38 | * FBXT_FSSM (strut FileSysStartupMsg *) 39 | * FSSM pointer. 40 | * 41 | * FBXT_DOSTYPE (ULONG) 42 | * Filesystem DOS type. 43 | * 44 | * FBXT_GET_CONTEXT (struct fuse_context *) 45 | * Filesystem context pointer. 46 | * 47 | * FBXT_ACTIVE_UPDATE_TIMEOUT (ULONG) 48 | * Active update timeout in milliseconds. 49 | * 50 | * FBXT_INACTIVE_UPDATE_TIMEOUT (ULONG) 51 | * Inactive update timeout in milliseconds. 52 | * 53 | * FBXT_GMT_OFFSET (LONG) 54 | * Returns a cached TZA_UTCOffset value. Its updated periodically 55 | * in case it changes because of a locale prefs change or because 56 | * of DST state change. Using GetTimezoneAttrs() directly from 57 | * any of the FUSE callbacks is not safe and can cause deadlocks. 58 | * 59 | * RESULT 60 | * This function does not return a result 61 | * 62 | * EXAMPLE 63 | * 64 | * NOTES 65 | * 66 | * BUGS 67 | * 68 | * SEE ALSO 69 | * 70 | ***************************************************************************** 71 | * 72 | */ 73 | 74 | #ifdef __AROS__ 75 | AROS_LH2(void, FbxQueryFS, 76 | AROS_LHA(struct FbxFS *, fs, A0), 77 | AROS_LHA(const struct TagItem *, tags, A1), 78 | struct FileSysBoxBase *, libBase, 18, FileSysBox) 79 | { 80 | AROS_LIBFUNC_INIT 81 | #else 82 | void FbxQueryFS( 83 | REG(a0, struct FbxFS *fs), 84 | REG(a1, const struct TagItem *tags), 85 | REG(a6, struct FileSysBoxBase *libBase)) 86 | { 87 | #endif 88 | struct Library *UtilityBase = libBase->utilitybase; 89 | struct TagItem *tstate; 90 | const struct TagItem *tag; 91 | 92 | tstate = (struct TagItem *)tags; 93 | while ((tag = NextTagItem(&tstate)) != NULL) 94 | { 95 | switch (tag->ti_Tag) 96 | { 97 | case FBXT_FSFLAGS: 98 | *(ULONG *)tag->ti_Data = fs->fsflags; 99 | break; 100 | 101 | case FBXT_FSSM: 102 | *(struct FileSysStartupMsg **)tag->ti_Data = fs->fssm; 103 | break; 104 | 105 | case FBXT_DOSTYPE: 106 | *(ULONG *)tag->ti_Data = fs->dostype; 107 | break; 108 | 109 | case FBXT_GET_CONTEXT: 110 | *(struct fuse_context **)tag->ti_Data = &fs->fcntx; 111 | break; 112 | 113 | case FBXT_ACTIVE_UPDATE_TIMEOUT: 114 | *(ULONG *)tag->ti_Data = fs->aut; 115 | break; 116 | 117 | case FBXT_INACTIVE_UPDATE_TIMEOUT: 118 | *(ULONG *)tag->ti_Data = fs->iaut; 119 | break; 120 | 121 | case FBXT_GMT_OFFSET: 122 | *(LONG *)tag->ti_Data = fs->gmtoffset; 123 | break; 124 | } 125 | } 126 | 127 | #ifdef __AROS__ 128 | AROS_LIBFUNC_EXIT 129 | #endif 130 | } 131 | -------------------------------------------------------------------------------- /include/inline/filesysbox.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated header (sfdc 1.12)! Do not edit! */ 2 | 3 | #ifndef _INLINE_FILESYSBOX_H 4 | #define _INLINE_FILESYSBOX_H 5 | 6 | #ifndef _SFDC_VARARG_DEFINED 7 | #define _SFDC_VARARG_DEFINED 8 | #ifdef __HAVE_IPTR_ATTR__ 9 | typedef APTR _sfdc_vararg __attribute__((iptr)); 10 | #else 11 | typedef ULONG _sfdc_vararg; 12 | #endif /* __HAVE_IPTR_ATTR__ */ 13 | #endif /* _SFDC_VARARG_DEFINED */ 14 | 15 | #ifndef __INLINE_MACROS_H 16 | #include 17 | #endif /* !__INLINE_MACROS_H */ 18 | 19 | #ifndef FILESYSBOX_BASE_NAME 20 | #define FILESYSBOX_BASE_NAME FileSysBoxBase 21 | #endif /* !FILESYSBOX_BASE_NAME */ 22 | 23 | #define FbxQueryMountMsg(___msg, ___attr) \ 24 | LP2(0x1e, APTR, FbxQueryMountMsg , struct Message *, ___msg, a0, LONG, ___attr, d0,\ 25 | , FILESYSBOX_BASE_NAME) 26 | 27 | #define FbxSetupFS(___msg, ___tags, ___ops, ___opssize, ___udata) \ 28 | LP5(0x24, struct FbxFS *, FbxSetupFS , struct Message *, ___msg, a0, const struct TagItem *, ___tags, a1, const struct fuse_operations *, ___ops, a2, LONG, ___opssize, d0, APTR, ___udata, a3,\ 29 | , FILESYSBOX_BASE_NAME) 30 | 31 | #define FbxEventLoop(___fs) \ 32 | LP1(0x2a, LONG, FbxEventLoop , struct FbxFS *, ___fs, a0,\ 33 | , FILESYSBOX_BASE_NAME) 34 | 35 | #define FbxCleanupFS(___fs) \ 36 | LP1NR(0x30, FbxCleanupFS , struct FbxFS *, ___fs, a0,\ 37 | , FILESYSBOX_BASE_NAME) 38 | 39 | #define FbxReturnMountMsg(___msg, ___r1, ___r2) \ 40 | LP3NR(0x36, FbxReturnMountMsg , struct Message *, ___msg, a0, SIPTR, ___r1, d0, SIPTR, ___r2, d1,\ 41 | , FILESYSBOX_BASE_NAME) 42 | 43 | #define FbxFuseVersion() \ 44 | LP0(0x3c, LONG, FbxFuseVersion ,\ 45 | , FILESYSBOX_BASE_NAME) 46 | 47 | #define FbxVersion() \ 48 | LP0(0x42, LONG, FbxVersion ,\ 49 | , FILESYSBOX_BASE_NAME) 50 | 51 | #define FbxSetSignalCallback(___fs, ___func, ___signals) \ 52 | LP3NR(0x48, FbxSetSignalCallback , struct FbxFS *, ___fs, a0, FbxSignalCallbackFunc, ___func, a1, ULONG, ___signals, d0,\ 53 | , FILESYSBOX_BASE_NAME) 54 | 55 | #define FbxInstallTimerCallback(___fs, ___func, ___period) \ 56 | LP3(0x4e, struct FbxTimerCallbackData *, FbxInstallTimerCallback , struct FbxFS *, ___fs, a0, FbxTimerCallbackFunc, ___func, a1, ULONG, ___period, d0,\ 57 | , FILESYSBOX_BASE_NAME) 58 | 59 | #define FbxUninstallTimerCallback(___fs, ___cb) \ 60 | LP2NR(0x54, FbxUninstallTimerCallback , struct FbxFS *, ___fs, a0, struct FbxTimerCallbackData *, ___cb, a1,\ 61 | , FILESYSBOX_BASE_NAME) 62 | 63 | #define FbxSignalDiskChange(___fs) \ 64 | LP1NR(0x5a, FbxSignalDiskChange , struct FbxFS *, ___fs, a0,\ 65 | , FILESYSBOX_BASE_NAME) 66 | 67 | #define FbxCopyStringBSTRToC(___src, ___dst, ___size) \ 68 | LP3NR(0x60, FbxCopyStringBSTRToC , BSTR, ___src, a0, STRPTR, ___dst, a1, ULONG, ___size, d0,\ 69 | , FILESYSBOX_BASE_NAME) 70 | 71 | #define FbxCopyStringCToBSTR(___src, ___dst, ___size) \ 72 | LP3NR(0x66, FbxCopyStringCToBSTR , CONST_STRPTR, ___src, a0, BSTR, ___dst, a1, ULONG, ___size, d0,\ 73 | , FILESYSBOX_BASE_NAME) 74 | 75 | #define FbxQueryFS(___fs, ___tags) \ 76 | LP2NR(0x6c, FbxQueryFS , struct FbxFS *, ___fs, a0, const struct TagItem *, ___tags, a1,\ 77 | , FILESYSBOX_BASE_NAME) 78 | 79 | #ifndef NO_INLINE_STDARG 80 | #define FbxQueryFSTags(___fs, ___tags, ...) \ 81 | ({_sfdc_vararg _tags[] = { ___tags, __VA_ARGS__ }; FbxQueryFS((___fs), (const struct TagItem *) _tags); }) 82 | #endif /* !NO_INLINE_STDARG */ 83 | 84 | #define FbxGetSysTime(___fs, ___tv) \ 85 | LP2NR(0x72, FbxGetSysTime , struct FbxFS *, ___fs, a0, struct timeval *, ___tv, a1,\ 86 | , FILESYSBOX_BASE_NAME) 87 | 88 | #define FbxGetUpTime(___fs, ___tv) \ 89 | LP2NR(0x78, FbxGetUpTime , struct FbxFS *, ___fs, a0, struct timeval *, ___tv, a1,\ 90 | , FILESYSBOX_BASE_NAME) 91 | 92 | #endif /* !_INLINE_FILESYSBOX_H */ 93 | -------------------------------------------------------------------------------- /src/diskchange.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef __AROS__ 17 | AROS_UFH5(int, FbxDiskChangeInterrupt, 18 | AROS_UFHA(APTR, data, A1), 19 | AROS_UFHA(APTR, code, A5), 20 | AROS_UFHA(struct ExecBase *, SysBase, A6), 21 | AROS_UFHA(APTR, mask, D1), 22 | AROS_UFHA(APTR, custom, A0)) 23 | { 24 | AROS_USERFUNC_INIT 25 | #else 26 | INTERRUPTPROTO(FbxDiskChangeInterrupt, int, APTR custom, APTR data) { 27 | #endif 28 | struct FbxFS *fs = data; 29 | struct FbxDiskChangeHandler *dch = fs->diskchangehandler; 30 | 31 | if (dch != NULL) { 32 | dch->func(fs); 33 | } 34 | 35 | return 0; 36 | 37 | #ifdef __AROS__ 38 | AROS_USERFUNC_EXIT 39 | #endif 40 | } 41 | 42 | struct FbxDiskChangeHandler *FbxAddDiskChangeHandler(struct FbxFS *fs, FbxDiskChangeHandlerFunc func) { 43 | struct Library *SysBase = fs->sysbase; 44 | struct FbxDiskChangeHandler *dch; 45 | struct FileSysStartupMsg *fssm = fs->fssm; 46 | struct MsgPort *mp = NULL; 47 | struct IOStdReq *io = NULL; 48 | struct Interrupt *interrupt = NULL; 49 | char devname[256]; 50 | 51 | dch = AllocPooled(fs->mempool, sizeof(*dch)); 52 | if (dch == NULL) goto cleanup; 53 | 54 | dch->func = func; 55 | 56 | mp = CreateMsgPort(); 57 | io = (struct IOStdReq *)CreateIORequest(mp, sizeof(*io)); 58 | if (io == NULL) goto cleanup; 59 | 60 | CopyStringBSTRToC(fssm->fssm_Device, devname, sizeof(devname)); 61 | if (OpenDevice((CONST_STRPTR)devname, fssm->fssm_Unit, (struct IORequest *)io, fssm->fssm_Flags) != 0) { 62 | io->io_Device = NULL; 63 | goto cleanup; 64 | } 65 | 66 | interrupt = AllocPooled(fs->mempool, sizeof(*interrupt)); 67 | if (interrupt == NULL) goto cleanup; 68 | 69 | bzero(interrupt, sizeof(*interrupt)); 70 | interrupt->is_Node.ln_Type = NT_INTERRUPT; 71 | #ifdef __AROS__ 72 | interrupt->is_Node.ln_Name = (char *)AROS_BSTR_ADDR(fs->devnode->dn_Name); 73 | interrupt->is_Code = (void (*)())FbxDiskChangeInterrupt; 74 | #else 75 | interrupt->is_Node.ln_Name = (char *)BADDR(fs->devnode->dn_Name) + 1; 76 | interrupt->is_Code = (void (*)())ENTRY(FbxDiskChangeInterrupt); 77 | #endif 78 | interrupt->is_Data = fs; 79 | 80 | io->io_Command = TD_ADDCHANGEINT; 81 | io->io_Data = interrupt; 82 | io->io_Length = sizeof(*interrupt); 83 | SendIO((struct IORequest *)io); 84 | 85 | dch->io = io; 86 | 87 | fs->diskchangehandler = dch; 88 | return dch; 89 | 90 | cleanup: 91 | FreePooled(fs->mempool, interrupt, sizeof(*interrupt)); 92 | if (io != NULL && io->io_Device != NULL) { 93 | CloseDevice((struct IORequest *)io); 94 | } 95 | DeleteIORequest((struct IORequest *)io); 96 | DeleteMsgPort(mp); 97 | FreePooled(fs->mempool, dch, sizeof(*dch)); 98 | 99 | return NULL; 100 | } 101 | 102 | void FbxRemDiskChangeHandler(struct FbxFS *fs) { 103 | struct FbxDiskChangeHandler *dch = fs->diskchangehandler; 104 | 105 | if (dch != NULL) { 106 | struct Library *SysBase = fs->sysbase; 107 | struct IOStdReq *io = dch->io; 108 | struct MsgPort *mp = io->io_Message.mn_ReplyPort; 109 | struct Interrupt *interrupt = (struct Interrupt *)io->io_Data; 110 | 111 | if (CheckIO((struct IORequest *)io) == NULL) { 112 | io->io_Command = TD_REMCHANGEINT; 113 | DoIO((struct IORequest *)io); 114 | } else { 115 | WaitIO((struct IORequest *)io); 116 | } 117 | 118 | CloseDevice((struct IORequest *)io); 119 | DeleteIORequest((struct IORequest *)io); 120 | DeleteMsgPort(mp); 121 | FreePooled(fs->mempool, interrupt, sizeof(*interrupt)); 122 | FreePooled(fs->mempool, dch, sizeof(*dch)); 123 | } 124 | } 125 | 126 | -------------------------------------------------------------------------------- /src/avl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #ifdef ENABLE_CHARSET_CONVERSION 12 | #include "filesysbox_internal.h" 13 | 14 | /* 15 | * AVL implementation based on information from: 16 | * https://en.wikipedia.org/wiki/AVL_tree 17 | */ 18 | 19 | static void rotate_left(struct FbxAVL *x, struct FbxAVL *z) { 20 | struct FbxAVL *t = z->left; 21 | x->right = t; 22 | if (t != NULL) t->parent = x; 23 | z->left = x; 24 | x->parent = z; 25 | } 26 | 27 | static void rotate_right(struct FbxAVL *x, struct FbxAVL *z) { 28 | struct FbxAVL *t = z->right; 29 | x->left = t; 30 | if (t != NULL) t->parent = x; 31 | z->right = x; 32 | x->parent = z; 33 | } 34 | 35 | static void retrace(struct FbxAVL **root, struct FbxAVL *z) { 36 | struct FbxAVL *g, *n, *x, *y; 37 | 38 | for (x = z->parent; x != NULL; x = z->parent) { 39 | if (z == x->right) { 40 | if (x->balance > 0) { 41 | g = x->parent; 42 | 43 | if (z->balance < 0) { 44 | y = z->left; 45 | 46 | rotate_right(z, y); 47 | rotate_left(x, y); 48 | 49 | if (y->balance == 0) { 50 | x->balance = 0; 51 | z->balance = 0; 52 | } else { 53 | if (y->balance > 0) { 54 | x->balance = -1; 55 | z->balance = 0; 56 | } else { 57 | x->balance = 0; 58 | z->balance = 1; 59 | } 60 | y->balance = 0; 61 | } 62 | n = y; 63 | } else { 64 | rotate_left(x, z); 65 | 66 | //assert(z->balance != 0); 67 | x->balance = 0; 68 | z->balance = 0; 69 | n = z; 70 | } 71 | } else if (x->balance < 0) { 72 | x->balance = 0; 73 | break; 74 | } else { 75 | x->balance = 1; 76 | z = x; 77 | continue; 78 | } 79 | } else { 80 | if (x->balance < 0) { 81 | g = x->parent; 82 | 83 | if (z->balance > 0) { 84 | y = z->right; 85 | 86 | rotate_left(z, y); 87 | rotate_right(x, y); 88 | 89 | if (y->balance == 0) { 90 | x->balance = 0; 91 | z->balance = 0; 92 | } else { 93 | if (y->balance < 0) { 94 | x->balance = 1; 95 | z->balance = 0; 96 | } else { 97 | x->balance = 0; 98 | z->balance = -1; 99 | } 100 | y->balance = 0; 101 | } 102 | n = y; 103 | } else { 104 | rotate_right(x, z); 105 | 106 | //assert(n->balance != 0); 107 | x->balance = 0; 108 | z->balance = 0; 109 | n = z; 110 | } 111 | } else if (x->balance > 0) { 112 | x->balance = 0; 113 | break; 114 | } else { 115 | x->balance = -1; 116 | z = x; 117 | continue; 118 | } 119 | } 120 | 121 | n->parent = g; 122 | if (g != NULL) { 123 | if (x == g->left) 124 | g->left = n; 125 | else 126 | g->right = n; 127 | } else 128 | *root = n; 129 | 130 | break; 131 | } 132 | } 133 | 134 | static BOOL insert(struct FbxAVL **root, struct FbxAVL *n) { 135 | struct FbxAVL *p = *root; 136 | 137 | n->left = NULL; 138 | n->right = NULL; 139 | n->balance = 0; 140 | 141 | if (p == NULL) { 142 | *root = n; 143 | n->parent = p; 144 | return TRUE; 145 | } 146 | 147 | for (;;) { 148 | if (n->unicode == p->unicode) 149 | return FALSE; 150 | 151 | if (n->unicode < p->unicode) { 152 | if (p->left != NULL) { 153 | p = p->left; 154 | continue; 155 | } 156 | p->left = n; 157 | } else { 158 | if (p->right != NULL) { 159 | p = p->right; 160 | continue; 161 | } 162 | p->right = n; 163 | } 164 | 165 | n->parent = p; 166 | retrace(root, n); 167 | 168 | return TRUE; 169 | } 170 | } 171 | 172 | void FbxSetupAVL(struct FbxFS *fs) { 173 | struct FbxAVL *n; 174 | ULONG unicode; 175 | int i, local; 176 | 177 | for (i = 0; i < 0x80; i++) { 178 | local = 0x80 + i; 179 | unicode = fs->maptable[local]; 180 | 181 | n = &fs->avlbuf[i]; 182 | n->unicode = unicode; 183 | n->local = local; 184 | 185 | insert(&fs->maptree, n); 186 | } 187 | } 188 | 189 | #endif /* ENABLE_CHARSET_CONVERSION */ 190 | 191 | -------------------------------------------------------------------------------- /src/notify.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | 13 | void FbxDoNotifyRequest(struct FbxFS *fs, struct NotifyRequest *nr) { 14 | struct Library *SysBase = fs->sysbase; 15 | struct NotifyMessage *notifymsg; 16 | 17 | NDEBUGF("FbxDoNotifyRequest(%#p, %#p)\n", fs, nr); 18 | 19 | if (nr->nr_Flags & NRF_SEND_MESSAGE) { 20 | if ((nr->nr_MsgCount > 0) && (nr->nr_Flags & NRF_WAIT_REPLY)) { 21 | nr->nr_Flags |= NRF_MAGIC; 22 | NDEBUGF("DoNotifyRequest: did magic! nreq %#p '%s'\n", nr, nr->nr_FullName); 23 | } else { 24 | notifymsg = AllocNotifyMessage(); 25 | if (!notifymsg) return; // lets abort. 26 | nr->nr_MsgCount++; 27 | notifymsg->nm_ExecMessage.mn_Length = sizeof(*notifymsg); 28 | notifymsg->nm_ExecMessage.mn_ReplyPort = fs->notifyreplyport; 29 | notifymsg->nm_Class = NOTIFY_CLASS; 30 | notifymsg->nm_Code = NOTIFY_CODE; 31 | notifymsg->nm_NReq = nr; 32 | PutMsg(nr->nr_stuff.nr_Msg.nr_Port, (struct Message *)notifymsg); 33 | NDEBUGF("DoNotifyRequest: sent message to port of nreq %#p '%s'\n", nr, nr->nr_FullName); 34 | } 35 | } else if (nr->nr_Flags & NRF_SEND_SIGNAL) { 36 | Signal(nr->nr_stuff.nr_Signal.nr_Task, 1 << nr->nr_stuff.nr_Signal.nr_SignalNum); 37 | NDEBUGF("DoNotifyRequest: signaled task of nreq %#p '%s'\n", nr, nr->nr_FullName); 38 | } 39 | } 40 | 41 | void FbxDoNotifyEntry(struct FbxFS *fs, struct FbxEntry *entry) { 42 | struct MinNode *nnchain; 43 | struct NotifyRequest *nr; 44 | struct FbxNotifyNode *nn; 45 | 46 | NDEBUGF("FbxDoNotifyEntry(%#p, %#p)\n", fs, entry); 47 | 48 | nnchain = entry->notifylist.mlh_Head; 49 | while (nnchain->mln_Succ) { 50 | nn = FSNOTIFYNODEFROMCHAIN(nnchain); 51 | nr = nn->nr; 52 | FbxDoNotifyRequest(fs, nr); 53 | nnchain = nnchain->mln_Succ; 54 | } 55 | } 56 | 57 | void FbxDoNotify(struct FbxFS *fs, const char *path) { 58 | struct FbxEntry *e; 59 | char pathbuf[FBX_MAX_PATH]; 60 | 61 | NDEBUGF("FbxDoNotify(%#p, '%s')\n", fs, path); 62 | 63 | FbxStrlcpy(fs, pathbuf, path, FBX_MAX_PATH); 64 | do { 65 | e = FbxFindEntry(fs, pathbuf); 66 | if (e != NULL) FbxDoNotifyEntry(fs, e); 67 | // parent dirs wants notify too 68 | } while (FbxParentPath(fs, pathbuf)); 69 | } 70 | 71 | void FbxTryResolveNotify(struct FbxFS *fs, struct FbxEntry *e) { 72 | struct Library *SysBase = fs->sysbase; 73 | struct FbxNotifyNode *nn; 74 | struct MinNode *chain, *succ; 75 | struct NotifyRequest *nr; 76 | const char *fullname; 77 | char fullpath[FBX_MAX_PATH]; 78 | #ifdef ENABLE_CHARSET_CONVERSION 79 | char fsfullname[FBX_MAX_PATH]; 80 | #endif 81 | 82 | NDEBUGF("FbxTryResolveNotify(%#p, %#p)\n", fs, e); 83 | 84 | chain = fs->currvol->unres_notifys.mlh_Head; 85 | while ((succ = chain->mln_Succ) != NULL) { 86 | nn = FSNOTIFYNODEFROMCHAIN(chain); 87 | nr = nn->nr; 88 | 89 | fullname = (const char *)nr->nr_FullName; 90 | #ifdef ENABLE_CHARSET_CONVERSION 91 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 92 | /* FIXME: Can the charset converted path be saved in FbxAddNotify 93 | * and then reused here? 94 | */ 95 | FbxLocalToUTF8(fs, fsfullname, fullname, FBX_MAX_PATH); 96 | fullname = fsfullname; 97 | } 98 | #endif 99 | 100 | if (FbxLockName2Path(fs, NULL, fullname, fullpath) && 101 | FbxStrcmp(fs, fullpath, e->path) == 0) 102 | { 103 | Remove((struct Node *)chain); 104 | AddTail((struct List *)&e->notifylist, (struct Node *)chain); 105 | nn->entry = e; 106 | PDEBUGF("try_resolve_nreqs: resolved nreq %#p, '%s'\n", nr, nr->nr_FullName); 107 | } 108 | chain = succ; 109 | } 110 | } 111 | 112 | void FbxUnResolveNotifys(struct FbxFS *fs, struct FbxEntry *e) { 113 | struct Library *SysBase = fs->sysbase; 114 | struct MinNode *chain, *succ; 115 | struct FbxNotifyNode *nn; 116 | 117 | NDEBUGF("unresolve_notifys(%#p, %#p)\n", fs, e); 118 | 119 | // move possible notifys onto unresolved list 120 | chain = e->notifylist.mlh_Head; 121 | while ((succ = chain->mln_Succ) != NULL) { 122 | Remove((struct Node *)chain); 123 | AddTail((struct List *)&fs->currvol->unres_notifys, (struct Node *)chain); 124 | nn = FSNOTIFYNODEFROMCHAIN(chain); 125 | NDEBUGF("unresolve_notifys: removed nn %#p\n", nn); 126 | nn->entry = NULL; // clear 127 | chain = succ; 128 | } 129 | 130 | NDEBUGF("unresolve_notifys: DONE\n"); 131 | } 132 | 133 | -------------------------------------------------------------------------------- /include/defines/filesysbox.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated header (sfdc 1.12)! Do not edit! */ 2 | 3 | #ifndef _INLINE_FILESYSBOX_H 4 | #define _INLINE_FILESYSBOX_H 5 | 6 | #include 7 | 8 | #ifndef AROS_LIBCALL_H 9 | #include 10 | #endif /* !AROS_LIBCALL_H */ 11 | 12 | #ifndef FILESYSBOX_BASE_NAME 13 | #define FILESYSBOX_BASE_NAME FileSysBoxBase 14 | #endif /* !FILESYSBOX_BASE_NAME */ 15 | 16 | #define FbxQueryMountMsg(___msg, ___attr) \ 17 | AROS_LC2(APTR, FbxQueryMountMsg, \ 18 | AROS_LCA(struct Message *, (___msg), A0), \ 19 | AROS_LCA(LONG, (___attr), D0), \ 20 | struct Library *, FILESYSBOX_BASE_NAME, 5, Filesysbox) 21 | 22 | #define FbxSetupFS(___msg, ___tags, ___ops, ___opssize, ___udata) \ 23 | AROS_LC5(struct FbxFS *, FbxSetupFS, \ 24 | AROS_LCA(struct Message *, (___msg), A0), \ 25 | AROS_LCA(const struct TagItem *, (___tags), A1), \ 26 | AROS_LCA(const struct fuse_operations *, (___ops), A2), \ 27 | AROS_LCA(LONG, (___opssize), D0), \ 28 | AROS_LCA(APTR, (___udata), A3), \ 29 | struct Library *, FILESYSBOX_BASE_NAME, 6, Filesysbox) 30 | 31 | #define FbxEventLoop(___fs) \ 32 | AROS_LC1(LONG, FbxEventLoop, \ 33 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 34 | struct Library *, FILESYSBOX_BASE_NAME, 7, Filesysbox) 35 | 36 | #define FbxCleanupFS(___fs) \ 37 | AROS_LC1NR(void, FbxCleanupFS, \ 38 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 39 | struct Library *, FILESYSBOX_BASE_NAME, 8, Filesysbox) 40 | 41 | #define FbxReturnMountMsg(___msg, ___r1, ___r2) \ 42 | AROS_LC3NR(void, FbxReturnMountMsg, \ 43 | AROS_LCA(struct Message *, (___msg), A0), \ 44 | AROS_LCA(SIPTR, (___r1), D0), \ 45 | AROS_LCA(SIPTR, (___r2), D1), \ 46 | struct Library *, FILESYSBOX_BASE_NAME, 9, Filesysbox) 47 | 48 | #define FbxFuseVersion() \ 49 | AROS_LC0(LONG, FbxFuseVersion, \ 50 | struct Library *, FILESYSBOX_BASE_NAME, 10, Filesysbox) 51 | 52 | #define FbxVersion() \ 53 | AROS_LC0(LONG, FbxVersion, \ 54 | struct Library *, FILESYSBOX_BASE_NAME, 11, Filesysbox) 55 | 56 | #define FbxSetSignalCallback(___fs, ___func, ___signals) \ 57 | AROS_LC3NR(void, FbxSetSignalCallback, \ 58 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 59 | AROS_LCA(FbxSignalCallbackFunc, (___func), A1), \ 60 | AROS_LCA(ULONG, (___signals), D0), \ 61 | struct Library *, FILESYSBOX_BASE_NAME, 12, Filesysbox) 62 | 63 | #define FbxInstallTimerCallback(___fs, ___func, ___period) \ 64 | AROS_LC3(struct FbxTimerCallbackData *, FbxInstallTimerCallback, \ 65 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 66 | AROS_LCA(FbxTimerCallbackFunc, (___func), A1), \ 67 | AROS_LCA(ULONG, (___period), D0), \ 68 | struct Library *, FILESYSBOX_BASE_NAME, 13, Filesysbox) 69 | 70 | #define FbxUninstallTimerCallback(___fs, ___cb) \ 71 | AROS_LC2NR(void, FbxUninstallTimerCallback, \ 72 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 73 | AROS_LCA(struct FbxTimerCallbackData *, (___cb), A1), \ 74 | struct Library *, FILESYSBOX_BASE_NAME, 14, Filesysbox) 75 | 76 | #define FbxSignalDiskChange(___fs) \ 77 | AROS_LC1NR(void, FbxSignalDiskChange, \ 78 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 79 | struct Library *, FILESYSBOX_BASE_NAME, 15, Filesysbox) 80 | 81 | #define FbxCopyStringBSTRToC(___src, ___dst, ___size) \ 82 | AROS_LC3NR(void, FbxCopyStringBSTRToC, \ 83 | AROS_LCA(BSTR, (___src), A0), \ 84 | AROS_LCA(STRPTR, (___dst), A1), \ 85 | AROS_LCA(ULONG, (___size), D0), \ 86 | struct Library *, FILESYSBOX_BASE_NAME, 16, Filesysbox) 87 | 88 | #define FbxCopyStringCToBSTR(___src, ___dst, ___size) \ 89 | AROS_LC3NR(void, FbxCopyStringCToBSTR, \ 90 | AROS_LCA(CONST_STRPTR, (___src), A0), \ 91 | AROS_LCA(BSTR, (___dst), A1), \ 92 | AROS_LCA(ULONG, (___size), D0), \ 93 | struct Library *, FILESYSBOX_BASE_NAME, 17, Filesysbox) 94 | 95 | #define FbxQueryFS(___fs, ___tags) \ 96 | AROS_LC2NR(void, FbxQueryFS, \ 97 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 98 | AROS_LCA(const struct TagItem *, (___tags), A1), \ 99 | struct Library *, FILESYSBOX_BASE_NAME, 18, Filesysbox) 100 | 101 | #ifndef NO_INLINE_STDARG 102 | #define FbxQueryFSTags(___fs, ...) \ 103 | ({ \ 104 | const IPTR FbxQueryFSTags_args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) };\ 105 | FbxQueryFS((___fs), (struct TagItem *)(FbxQueryFSTags_args)); \ 106 | }) 107 | #endif /* !NO_INLINE_STDARG */ 108 | 109 | #define FbxGetSysTime(___fs, ___tv) \ 110 | AROS_LC2NR(void, FbxGetSysTime, \ 111 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 112 | AROS_LCA(struct timeval *, (___tv), A1), \ 113 | struct Library *, FILESYSBOX_BASE_NAME, 19, Filesysbox) 114 | 115 | #define FbxGetUpTime(___fs, ___tv) \ 116 | AROS_LC2NR(void, FbxGetUpTime, \ 117 | AROS_LCA(struct FbxFS *, (___fs), A0), \ 118 | AROS_LCA(struct timeval *, (___tv), A1), \ 119 | struct Library *, FILESYSBOX_BASE_NAME, 20, Filesysbox) 120 | 121 | #endif /* !_INLINE_FILESYSBOX_H */ 122 | -------------------------------------------------------------------------------- /src/fsexaminelock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | #include 15 | 16 | LONG FbxMode2EntryType(const mode_t mode) { 17 | if (S_ISDIR(mode)) { 18 | return ST_USERDIR; 19 | } else if (S_ISREG(mode)) { 20 | return ST_FILE; 21 | } else if (S_ISLNK(mode)) { 22 | return ST_SOFTLINK; 23 | } else { // whatever.. 24 | return ST_PIPEFILE; 25 | } 26 | } 27 | 28 | ULONG FbxMode2Protection(const mode_t mode) { 29 | ULONG prot = FIBF_READ|FIBF_WRITE|FIBF_EXECUTE|FIBF_DELETE; 30 | 31 | if (mode & S_IRUSR) prot &= ~(FIBF_READ); 32 | if (mode & S_IWUSR) prot &= ~(FIBF_WRITE|FIBF_DELETE); 33 | if (mode & S_IXUSR) prot &= ~(FIBF_EXECUTE); 34 | if (mode & S_IRGRP) prot |= FIBF_GRP_READ; 35 | if (mode & S_IWGRP) prot |= FIBF_GRP_WRITE|FIBF_GRP_DELETE; 36 | if (mode & S_IXGRP) prot |= FIBF_GRP_EXECUTE; 37 | if (mode & S_IROTH) prot |= FIBF_OTR_READ; 38 | if (mode & S_IWOTH) prot |= FIBF_OTR_WRITE|FIBF_OTR_DELETE; 39 | if (mode & S_IXOTH) prot |= FIBF_OTR_EXECUTE; 40 | 41 | return prot; 42 | } 43 | 44 | UWORD FbxUnix2AmigaOwner(const uid_t owner) { 45 | if (owner == (uid_t)0) return DOS_OWNER_ROOT; 46 | else if (owner == (uid_t)-2) return DOS_OWNER_NONE; 47 | else return (UWORD)owner; 48 | } 49 | 50 | static const char *FbxFilePart(const char *path) { 51 | const char *name = strrchr(path, '/'); 52 | return name ? (name + 1) : path; 53 | } 54 | 55 | void FbxPathStat2FIB(struct FbxFS *fs, const char *fullpath, struct fbx_stat *stat, 56 | struct FileInfoBlock *fib) 57 | { 58 | char comment[FBX_MAX_COMMENT]; 59 | #ifdef ENABLE_CHARSET_CONVERSION 60 | char adname[FBX_MAX_NAME]; 61 | char adcomment[FBX_MAX_COMMENT]; 62 | #endif 63 | const char *name, *pcomment; 64 | LONG type; 65 | 66 | if (IsRoot(fullpath)) { 67 | name = fs->currvol->volname; 68 | type = ST_ROOT; 69 | } else { 70 | name = FbxFilePart(fullpath); 71 | type = FbxMode2EntryType(stat->st_mode); 72 | #ifdef ENABLE_CHARSET_CONVERSION 73 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 74 | FbxUTF8ToLocal(fs, adname, name, FBX_MAX_NAME); 75 | name = adname; 76 | } 77 | #endif 78 | } 79 | 80 | #ifdef ENABLE_CHARSET_CONVERSION 81 | strlcpy((char *)fib->fib_FileName + 1, name, sizeof(fib->fib_FileName)); 82 | #else 83 | FbxStrlcpy(fs, (char *)fib->fib_FileName + 1, name, sizeof(fib->fib_FileName)); 84 | #endif 85 | fib->fib_FileName[0] = strlen((char *)fib->fib_FileName + 1); 86 | 87 | fib->fib_DirEntryType = fib->fib_EntryType = type; 88 | 89 | pcomment = comment; 90 | FbxGetComment(fs, fullpath, comment, FBX_MAX_COMMENT); 91 | #ifdef ENABLE_CHARSET_CONVERSION 92 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 93 | FbxUTF8ToLocal(fs, adcomment, comment, FBX_MAX_COMMENT); 94 | pcomment = adcomment; 95 | } 96 | #endif 97 | 98 | #ifdef ENABLE_CHARSET_CONVERSION 99 | strlcpy((char *)fib->fib_Comment + 1, pcomment, sizeof(fib->fib_Comment)); 100 | #else 101 | FbxStrlcpy(fs, (char *)fib->fib_Comment + 1, pcomment, sizeof(fib->fib_Comment)); 102 | #endif 103 | fib->fib_Comment[0] = strlen((char *)fib->fib_Comment + 1); 104 | 105 | if (stat->st_size < 0) 106 | fib->fib_Size = 0; 107 | else if (sizeof(fib->fib_Size) == 4 && stat->st_size >= INT32_MAX) 108 | fib->fib_Size = INT32_MAX-1; 109 | else 110 | fib->fib_Size = stat->st_size; 111 | 112 | fib->fib_Protection = FbxMode2Protection(stat->st_mode); 113 | fib->fib_Protection |= FbxGetAmigaProtectionFlags(fs, fullpath); 114 | fib->fib_NumBlocks = stat->st_blocks; 115 | 116 | if (fs->fsflags & FBXF_USE_INO) 117 | fib->fib_DiskKey = (IPTR)stat->st_ino; 118 | else 119 | fib->fib_DiskKey = (IPTR)FbxHashPath(fs, fullpath); 120 | 121 | FbxTimeSpec2DS(fs, &stat->st_mtim, &fib->fib_Date); 122 | 123 | fib->fib_OwnerUID = FbxUnix2AmigaOwner(stat->st_uid); 124 | fib->fib_OwnerGID = FbxUnix2AmigaOwner(stat->st_gid); 125 | } 126 | 127 | int FbxExamineLock(struct FbxFS *fs, struct FbxLock *lock, struct FileInfoBlock *fib) { 128 | struct fbx_stat statbuf; 129 | int error; 130 | 131 | PDEBUGF("FbxExamineLock(%#p, %#p, %#p)\n", fs, lock, fib); 132 | 133 | CHECKVOLUME(DOSFALSE); 134 | 135 | CHECKLOCK(lock, DOSFALSE); 136 | 137 | if (lock->fsvol != fs->currvol) { 138 | fs->r2 = ERROR_NO_DISK; 139 | return DOSFALSE; 140 | } 141 | 142 | FreeFbxDirDataList(lock, &lock->dirdatalist); 143 | 144 | if (!lock->info) { 145 | error = Fbx_getattr(fs, lock->entry->path, &statbuf); 146 | } else { 147 | error = Fbx_fgetattr(fs, lock->entry->path, &statbuf, lock->info); 148 | } 149 | if (error) { 150 | fs->r2 = FbxFuseErrno2Error(error); 151 | return DOSFALSE; 152 | } 153 | FbxPathStat2FIB(fs, lock->entry->path, &statbuf, fib); 154 | lock->dirscan = FALSE; 155 | fs->r2 = 0; 156 | return DOSTRUE; 157 | } 158 | 159 | -------------------------------------------------------------------------------- /src/fsexaminenext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | 15 | static int Fbx_opendir(struct FbxFS *fs, const char *path, struct fuse_file_info *fi) 16 | { 17 | ODEBUGF("Fbx_opendir(%#p, '%s', %#p)\n", fs, path, fi); 18 | 19 | return FSOP opendir(path, fi, &fs->fcntx); 20 | } 21 | 22 | static int Fbx_releasedir(struct FbxFS *fs, const char *path, struct fuse_file_info *fi) 23 | { 24 | ODEBUGF("Fbx_releasedir(%#p, '%s', %#p)\n", fs, path, fi); 25 | 26 | return FSOP releasedir(path, fi, &fs->fcntx); 27 | } 28 | 29 | static int Fbx_readdir(struct FbxFS *fs, const char *path, APTR udata, fuse_fill_dir_t func, 30 | QUAD offset, struct fuse_file_info *fi) 31 | { 32 | ODEBUGF("Fbx_readdir(%#p, '%s', %#p, %#p, %lld, %#p)\n", fs, path, udata, func, offset, fi); 33 | 34 | return FSOP readdir(path, udata, func, offset, fi, &fs->fcntx); 35 | } 36 | 37 | static STDARGS int dir_fill_func(void *udata, const char *name, const struct fbx_stat *stat, fbx_off_t offset) { 38 | struct FbxLock *lock = udata; 39 | struct FbxFS *fs = lock->fs; 40 | struct Library *SysBase = fs->sysbase; 41 | struct FbxDirData *ed; 42 | size_t len; 43 | 44 | if (name == NULL) return 2; 45 | 46 | if (!IsDotOrDotDot(name)) { 47 | if (FbxCheckString(fs, name)) { 48 | len = strlen(name) + 1; 49 | ed = AllocFbxDirData(lock, len); 50 | if (ed == NULL) return 1; 51 | 52 | ed->fsname = (char *)(ed + 1); 53 | 54 | /* Only used by ExAll() */ 55 | ed->name = NULL; 56 | ed->comment = NULL; 57 | 58 | FbxStrlcpy(fs, ed->fsname, name, len); 59 | if (stat != NULL) 60 | { 61 | ed->stat = *stat; 62 | } 63 | else 64 | { 65 | ed->stat.st_ino = 0; 66 | } 67 | 68 | AddTail((struct List *)&lock->dirdatalist, (struct Node *)ed); 69 | } 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | int FbxReadDir(struct FbxFS *fs, struct FbxLock *lock) { 76 | int error; 77 | 78 | if (FSOP opendir != FSOP open) { 79 | struct Library *SysBase = fs->sysbase; 80 | struct fuse_file_info *fi; 81 | 82 | fi = AllocFuseFileInfo(fs); 83 | if (fi == NULL) { 84 | fs->r2 = ERROR_NO_FREE_STORE; 85 | return DOSFALSE; 86 | } 87 | bzero(fi, sizeof(*fi)); 88 | 89 | error = Fbx_opendir(fs, lock->entry->path, fi); 90 | if (error) { 91 | FreeFuseFileInfo(fs, fi); 92 | fs->r2 = FbxFuseErrno2Error(error); 93 | return DOSFALSE; 94 | } 95 | 96 | error = Fbx_readdir(fs, lock->entry->path, lock, dir_fill_func, 0, fi); 97 | if (error) { 98 | Fbx_releasedir(fs, lock->entry->path, fi); 99 | FreeFuseFileInfo(fs, fi); 100 | fs->r2 = FbxFuseErrno2Error(error); 101 | return DOSFALSE; 102 | } 103 | 104 | Fbx_releasedir(fs, lock->entry->path, fi); 105 | FreeFuseFileInfo(fs, fi); 106 | } else { 107 | error = Fbx_readdir(fs, lock->entry->path, lock, dir_fill_func, 0, NULL); 108 | if (error) { 109 | fs->r2 = FbxFuseErrno2Error(error); 110 | return DOSFALSE; 111 | } 112 | } 113 | 114 | return DOSTRUE; 115 | } 116 | 117 | int FbxExamineNext(struct FbxFS *fs, struct FbxLock *lock, struct FileInfoBlock *fib) { 118 | struct Library *SysBase = fs->sysbase; 119 | struct FbxDirData *ed; 120 | struct fbx_stat statbuf; 121 | int error; 122 | char fullpath[FBX_MAX_PATH]; 123 | 124 | PDEBUGF("FbxExamineNext(%#p, %#p, %#p)\n", fs, lock, fib); 125 | 126 | CHECKVOLUME(DOSFALSE); 127 | 128 | CHECKLOCK(lock, DOSFALSE); 129 | 130 | if (lock->fsvol != fs->currvol) { 131 | fs->r2 = ERROR_NO_DISK; 132 | return DOSFALSE; 133 | } 134 | 135 | if (!lock->dirscan) { 136 | if (lock->mempool == NULL) { 137 | lock->mempool = CreatePool(MEMF_PUBLIC, 4096, 1024); 138 | if (lock->mempool == NULL) { 139 | fs->r2 = ERROR_NO_FREE_STORE; 140 | return DOSFALSE; 141 | } 142 | } 143 | 144 | if (!FbxReadDir(fs, lock)) { 145 | FreeFbxDirDataList(lock, &lock->dirdatalist); 146 | return DOSFALSE; 147 | } 148 | lock->dirscan = TRUE; 149 | } 150 | 151 | ed = (struct FbxDirData *)RemHead((struct List *)&lock->dirdatalist); 152 | if (ed == NULL) { 153 | fs->r2 = ERROR_NO_MORE_ENTRIES; 154 | return DOSFALSE; 155 | } 156 | 157 | if (!FbxLockName2Path(fs, lock, ed->fsname, fullpath)) { 158 | FreeFbxDirData(lock, ed); 159 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 160 | return DOSFALSE; 161 | } 162 | 163 | if (fs->fsflags & FBXF_USE_FILL_DIR_STAT) { 164 | statbuf = ed->stat; 165 | FreeFbxDirData(lock, ed); 166 | } else { 167 | FreeFbxDirData(lock, ed); 168 | error = Fbx_getattr(fs, fullpath, &statbuf); 169 | if (error) { 170 | fs->r2 = FbxFuseErrno2Error(error); 171 | return DOSFALSE; 172 | } 173 | } 174 | 175 | FbxPathStat2FIB(fs, fullpath, &statbuf, fib); 176 | 177 | fs->r2 = 0; 178 | return DOSTRUE; 179 | } 180 | 181 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | #HOST ?= x86_64-aros 2 | HOST ?= i386-aros 3 | DEBUG ?= 0 4 | 5 | CC = $(HOST)-gcc 6 | STRIP = $(HOST)-strip 7 | 8 | TARGET = filesysbox.library 9 | VERSION = 54 10 | 11 | INCLUDES = -I./include -I. -I./src 12 | DEFINES = -D__NOLIBBASE__ 13 | WARNINGS = -Werror -Wall -Wwrite-strings -Wno-attributes 14 | 15 | ifneq (1,$(DEBUG)) 16 | DEFINES += -DNODEBUG 17 | BINDIR = bin 18 | OBJDIR = obj 19 | else 20 | BINDIR = bin/debug 21 | OBJDIR = obj/debug 22 | endif 23 | 24 | DEFINES += -DENABLE_CHARSET_CONVERSION 25 | 26 | CFLAGS = -O2 -g -fomit-frame-pointer -fno-strict-aliasing \ 27 | $(INCLUDES) $(DEFINES) $(WARNINGS) 28 | LDFLAGS = -nostartfiles 29 | LIBS = 30 | STRIPFLAGS = -R.comment 31 | 32 | ifneq (,$(SYSROOT)) 33 | CFLAGS := --sysroot=$(SYSROOT) $(CFLAGS) 34 | LDFLAGS := --sysroot=$(SYSROOT) $(LDFLAGS) 35 | endif 36 | 37 | ifneq (,$(findstring -aros,$(HOST))) 38 | CPU = $(patsubst %-aros,%,$(HOST)) 39 | LIBS += -lstdc.static 40 | endif 41 | 42 | ifeq ($(HOST),m68k-amigaos) 43 | DEFINES += -DENABLE_DP64_SUPPORT 44 | ARCH_000 = -mcpu=68000 -mtune=68000 45 | ARCH_020 = -mcpu=68020 -mtune=68020-60 46 | ARCH_060 = -mcpu=68060 -mtune=68060 47 | CFLAGS := -noixemul -fno-common -mregparm $(CFLAGS) 48 | LDFLAGS := -noixemul $(LDFLAGS) 49 | endif 50 | 51 | main_SRCS = $(wildcard src/main/*.c) 52 | 53 | SRCS = $(addprefix src/, \ 54 | init.c filesysbox.c diskchange.c timer.c notify.c doslist.c lockhandler.c \ 55 | fuse_stubs.c dopacket.c dopacket64.c fsaddnotify.c fschangefileposition.c \ 56 | fschangefilesize.c fschangemode.c fsclose.c fscreatedir.c fscreatehardlink.c \ 57 | fscreatesoftlink.c fscurrentvolume.c fsdelete.c fsdie.c fsduplock.c \ 58 | fsexamineall.c fsexamineallend.c fsexaminelock.c fsexaminenext.c fsformat.c \ 59 | fsgetfileposition.c fsgetfilesize.c fsinfodata.c fsinhibit.c fslock.c fsopen.c \ 60 | fsopenfromlock.c fsparentdir.c fsread.c fsreadlink.c fsrelabel.c \ 61 | fsremovenotify.c fsrename.c fssamelock.c fsseek.c fssetcomment.c fssetdate.c \ 62 | fssetfilesize.c fssetownerinfo.c fssetprotection.c fsunlock.c fswrite.c \ 63 | fswriteprotect.c volume.c xattrs.c utf8.c ucs4.c strlcpy.c debugf.c dofmt.c \ 64 | allocvecpooled.c codesets.c avl.c) 65 | 66 | ifeq ($(HOST),m68k-amigaos) 67 | OBJS_000 = $(subst src/,$(OBJDIR)/68000/,$(main_SRCS:.c=.o) $(SRCS:.c=.o)) 68 | OBJS_020 = $(subst src/,$(OBJDIR)/68020/,$(main_SRCS:.c=.o) $(SRCS:.c=.o)) 69 | OBJS_060 = $(subst src/,$(OBJDIR)/68060/,$(main_SRCS:.c=.o) $(SRCS:.c=.o)) 70 | DEPS_000 = $(OBJS_000:.o=.d) 71 | DEPS_020 = $(OBJS_020:.o=.d) 72 | DEPS_060 = $(OBJS_060:.o=.d) 73 | else 74 | OBJS = $(subst src/,$(OBJDIR)/$(CPU)/,$(main_SRCS:.c=.o) $(SRCS:.c=.o)) 75 | DEPS = $(OBJS:.o=.d) 76 | endif 77 | 78 | .PHONY: all 79 | ifeq ($(HOST),m68k-amigaos) 80 | all: $(BINDIR)/$(TARGET).000 $(BINDIR)/$(TARGET).020 $(BINDIR)/$(TARGET).060 81 | else 82 | all: $(BINDIR)/$(TARGET).$(CPU) $(BINDIR)/$(TARGET).$(CPU).debug 83 | endif 84 | 85 | -include $(DEPS) 86 | 87 | $(OBJDIR)/$(CPU)/%.o: src/%.c 88 | @mkdir -p $(dir $@) 89 | $(CC) -MM -MP -MT $(@:.o=.d) -MT $@ -MF $(@:.o=.d) $(CFLAGS) $< 90 | $(CC) $(CFLAGS) -c -o $@ $< 91 | 92 | $(BINDIR)/$(TARGET).$(CPU).debug: $(OBJS) 93 | @mkdir -p $(dir $@) 94 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 95 | 96 | ifneq (,$(findstring -aros,$(HOST))) 97 | $(BINDIR)/$(TARGET).$(CPU): $(OBJS) 98 | @mkdir -p $(dir $@) 99 | $(CC) -s $(LDFLAGS) -o $@ $^ $(LIBS) 100 | else 101 | $(BINDIR)/$(TARGET).$(CPU): $(BINDIR)/$(TARGET).$(CPU).debug 102 | @mkdir -p $(dir $@) 103 | $(STRIP) $(STRIPFLAGS) -o $@ $< 104 | endif 105 | 106 | ifeq ($(HOST),m68k-amigaos) 107 | -include $(DEPS_000) 108 | -include $(DEPS_020) 109 | -include $(DEPS_060) 110 | 111 | $(OBJDIR)/68000/%.o: src/%.c 112 | @mkdir -p $(dir $@) 113 | $(CC) -MM -MP -MT $(@:.o=.d) -MT $@ -MF $(@:.o=.d) $(ARCH_000) $(CFLAGS) $< 114 | $(CC) $(ARCH_000) $(CFLAGS) -c -o $@ $< 115 | 116 | $(OBJDIR)/68020/%.o: src/%.c 117 | @mkdir -p $(dir $@) 118 | $(CC) -MM -MP -MT $(@:.o=.d) -MT $@ -MF $(@:.o=.d) $(ARCH_020) $(CFLAGS) $< 119 | $(CC) $(ARCH_020) $(CFLAGS) -c -o $@ $< 120 | 121 | $(OBJDIR)/68060/%.o: src/%.c 122 | @mkdir -p $(dir $@) 123 | $(CC) -MM -MP -MT $(@:.o=.d) -MT $@ -MF $(@:.o=.d) $(ARCH_060) $(CFLAGS) $< 124 | $(CC) $(ARCH_060) $(CFLAGS) -c -o $@ $< 125 | 126 | $(BINDIR)/$(TARGET).000: $(OBJS_000) 127 | @mkdir -p $(dir $@) 128 | $(CC) $(ARCH_000) $(LDFLAGS) -o $@.debug $^ $(LIBS) 129 | $(STRIP) $(STRIPFLAGS) -o $@ $@.debug 130 | 131 | $(BINDIR)/$(TARGET).020: $(OBJS_020) 132 | @mkdir -p $(dir $@) 133 | $(CC) $(ARCH_020) $(LDFLAGS) -o $@.debug $^ $(LIBS) 134 | $(STRIP) $(STRIPFLAGS) -o $@ $@.debug 135 | 136 | $(BINDIR)/$(TARGET).060: $(OBJS_060) 137 | @mkdir -p $(dir $@) 138 | $(CC) $(ARCH_060) $(LDFLAGS) -o $@.debug $^ $(LIBS) 139 | $(STRIP) $(STRIPFLAGS) -o $@ $@.debug 140 | endif 141 | 142 | .PHONY: clean 143 | clean: 144 | rm -rf bin obj 145 | 146 | .PHONY: revision 147 | revision: 148 | bumprev -e si $(VERSION) $(TARGET) 149 | 150 | .PHONY: autodoc 151 | autodoc: 152 | autodoc -l100 src/filesysbox_internal.h $(SRCS) $(main_SRCS) >filesysbox.doc 153 | 154 | -------------------------------------------------------------------------------- /src/fsrename.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | #include 15 | 16 | static int Fbx_rename(struct FbxFS *fs, const char *path, const char *path2) 17 | { 18 | ODEBUGF("Fbx_rename(%#p, '%s', '%s')\n", fs, path, path2); 19 | 20 | return FSOP rename(path, path2, &fs->fcntx); 21 | } 22 | 23 | static void FbxUpdatePaths(struct FbxFS *fs, const char *oldpath, const char *newpath) { 24 | struct Library *SysBase = fs->sysbase; 25 | char tstr[FBX_MAX_PATH]; 26 | struct MinNode *chain, *succ; 27 | 28 | // TODO: unresolve+tryresolve notify for affected entries.. 29 | 30 | // lets rename all subentries. subentries can be 31 | // found by comparing common path. do this by traversing 32 | // global hashtable and compare entry->path 33 | int plen = FbxStrlen(fs, oldpath); 34 | int a; 35 | if (IsRoot(oldpath)) plen = 0; 36 | for (a = 0; a < ENTRYHASHSIZE; a++) { 37 | chain = fs->currvol->entrytab[a].mlh_Head; 38 | while ((succ = chain->mln_Succ) != NULL) { 39 | struct FbxEntry *e = FSENTRYFROMHASHCHAIN(chain); 40 | if (FbxStrncmp(fs, oldpath, e->path, plen) == 0 && e->path[plen] == '/') { 41 | // match! let's update path 42 | FbxStrlcpy(fs, tstr, newpath, FBX_MAX_PATH); 43 | FbxStrlcat(fs, tstr, e->path + plen, FBX_MAX_PATH); 44 | FbxSetEntryPath(fs, e, tstr); 45 | // and rehash it 46 | Remove((struct Node *)&e->hashchain); 47 | FbxAddEntry(fs, e); 48 | } 49 | chain = succ; 50 | } 51 | } 52 | } 53 | 54 | int FbxRenameObject(struct FbxFS *fs, struct FbxLock *lock, const char *name, 55 | struct FbxLock *lock2, const char *name2) 56 | { 57 | struct Library *SysBase = fs->sysbase; 58 | struct FbxEntry *e, *e2; 59 | struct fbx_stat statbuf; 60 | int error; 61 | char fullpath[FBX_MAX_PATH]; 62 | char fullpath2[FBX_MAX_PATH]; 63 | #ifdef ENABLE_CHARSET_CONVERSION 64 | char fsname[FBX_MAX_NAME]; 65 | char fsname2[FBX_MAX_NAME]; 66 | #endif 67 | 68 | CHECKVOLUME(DOSFALSE); 69 | CHECKWRITABLE(DOSFALSE); 70 | 71 | if (lock != NULL) { 72 | CHECKLOCK(lock, DOSFALSE); 73 | 74 | if (lock->fsvol != fs->currvol) { 75 | fs->r2 = ERROR_NO_DISK; 76 | return DOSFALSE; 77 | } 78 | } 79 | if (lock2 != NULL) { 80 | CHECKLOCK(lock2, DOSFALSE); 81 | 82 | if (lock2->fsvol != fs->currvol) { 83 | fs->r2 = ERROR_NO_DISK; 84 | return DOSFALSE; 85 | } 86 | } 87 | 88 | #ifdef ENABLE_CHARSET_CONVERSION 89 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 90 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 91 | fs->r2 = ERROR_LINE_TOO_LONG; 92 | return DOSFALSE; 93 | } 94 | name = fsname; 95 | if (FbxLocalToUTF8(fs, fsname2, name2, FBX_MAX_NAME) >= FBX_MAX_NAME) { 96 | fs->r2 = ERROR_LINE_TOO_LONG; 97 | return DOSFALSE; 98 | } 99 | name2 = fsname2; 100 | } 101 | #else 102 | CHECKSTRING(name, DOSFALSE); 103 | CHECKSTRING(name2, DOSFALSE); 104 | #endif 105 | 106 | if (!FbxLockName2Path(fs, lock, name, fullpath) || 107 | !FbxLockName2Path(fs, lock2, name2, fullpath2)) 108 | { 109 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 110 | return DOSFALSE; 111 | } 112 | 113 | if (IsRoot(fullpath)) { 114 | // can't rename root 115 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 116 | return DOSFALSE; 117 | } 118 | 119 | if (FbxIsParent(fs, fullpath, fullpath2)) { 120 | fs->r2 = ERROR_OBJECT_IN_USE; 121 | return DOSFALSE; 122 | } 123 | 124 | /* Make sure that the object to be renamed exists */ 125 | e = FbxFindEntry(fs, fullpath); 126 | if (e == NULL) 127 | { 128 | error = Fbx_getattr(fs, fullpath, &statbuf); 129 | if (error) 130 | { 131 | fs->r2 = FbxFuseErrno2Error(error); 132 | return DOSFALSE; 133 | } 134 | } 135 | 136 | /* Check if source and destination are the same object */ 137 | if (FbxStrcmp(fs, fullpath, fullpath2) == 0) 138 | { 139 | if ((fs->currvol->vflags & FBXVF_CASE_SENSITIVE) || strcmp(fullpath, fullpath2) == 0) 140 | { 141 | /* Nothing to do here */ 142 | fs->r2 = 0; 143 | return DOSTRUE; 144 | } 145 | } 146 | else 147 | { 148 | /* Check if destination already exists */ 149 | e2 = FbxFindEntry(fs, fullpath2); 150 | if (e2 != NULL) { 151 | fs->r2 = ERROR_OBJECT_EXISTS; 152 | return DOSFALSE; 153 | } 154 | error = Fbx_getattr(fs, fullpath2, &statbuf); 155 | if (error == 0) { 156 | fs->r2 = ERROR_OBJECT_EXISTS; 157 | return DOSFALSE; 158 | } else if (error != -ENOENT) { 159 | fs->r2 = FbxFuseErrno2Error(error); 160 | return DOSFALSE; 161 | } 162 | } 163 | 164 | error = Fbx_rename(fs, fullpath, fullpath2); 165 | if (error) { 166 | fs->r2 = FbxFuseErrno2Error(error); 167 | return DOSFALSE; 168 | } 169 | 170 | FbxDoNotify(fs, fullpath); 171 | 172 | //e = FbxFindEntry(fs, fullpath); /* Already done in code above */ 173 | if (e != NULL) { 174 | FbxUnResolveNotifys(fs, e); 175 | FbxSetEntryPath(fs, e, fullpath2); 176 | Remove((struct Node *)&e->hashchain); 177 | FbxAddEntry(fs, e); 178 | FbxTryResolveNotify(fs, e); 179 | } 180 | 181 | FbxDoNotify(fs, fullpath2); 182 | 183 | FbxUpdatePaths(fs, fullpath, fullpath2); 184 | 185 | FbxSetModifyState(fs, 1); 186 | 187 | fs->r2 = 0; 188 | return DOSTRUE; 189 | } 190 | 191 | -------------------------------------------------------------------------------- /src/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #include 9 | #include 10 | #include "filesysbox_internal.h" 11 | #include "filesysbox.library_rev.h" 12 | 13 | static const char USED_VAR verstag[] = VERSTAG; 14 | 15 | struct Library *SysBase; 16 | #ifdef libnix 17 | //struct Library *__UtilityBase; 18 | struct Library *UtilityBase; 19 | #endif 20 | static inline void SetGlobalSysBase(struct Library *sysbase) { 21 | SysBase = sysbase; 22 | } 23 | 24 | #ifdef __AROS__ 25 | static AROS_UFH3(struct FileSysBoxBase *, LibInit, 26 | AROS_UFHA(struct FileSysBoxBase *, libBase, D0), 27 | AROS_UFHA(BPTR, seglist, A0), 28 | AROS_UFHA(struct Library *, SysBase, A6)) 29 | { 30 | AROS_USERFUNC_INIT 31 | #else 32 | static struct FileSysBoxBase *LibInit (REG(d0, struct FileSysBoxBase *libBase), 33 | REG(a0, BPTR seglist), REG(a6, struct Library *SysBase)) 34 | { 35 | #endif 36 | 37 | libBase->libnode.lib_Node.ln_Type = NT_LIBRARY; 38 | libBase->libnode.lib_Node.ln_Pri = 0; 39 | libBase->libnode.lib_Node.ln_Name = (char *)"filesysbox.library"; 40 | libBase->libnode.lib_Flags = LIBF_SUMUSED|LIBF_CHANGED; 41 | libBase->libnode.lib_Version = VERSION; 42 | libBase->libnode.lib_Revision = REVISION; 43 | libBase->libnode.lib_IdString = (STRPTR)VSTRING; 44 | 45 | libBase->seglist = seglist; 46 | libBase->sysbase = SysBase; 47 | 48 | libBase->dosbase = OpenLibrary((CONST_STRPTR)"dos.library", 39); 49 | if (libBase->dosbase == NULL) { 50 | Alert(AG_OpenLib|AO_DOSLib); 51 | goto error; 52 | } 53 | 54 | libBase->utilitybase = OpenLibrary((CONST_STRPTR)"utility.library", 39); 55 | if (libBase->utilitybase == NULL) { 56 | Alert(AG_OpenLib|AO_UtilityLib); 57 | goto error; 58 | } 59 | 60 | libBase->localebase = OpenLibrary((CONST_STRPTR)"locale.library", 38); 61 | 62 | SetGlobalSysBase(SysBase); 63 | #ifdef libnix 64 | //__UtilityBase = libBase->utilitybase; 65 | UtilityBase = libBase->utilitybase; 66 | #endif 67 | 68 | InitSemaphore(&libBase->procsema); 69 | 70 | return libBase; 71 | 72 | error: 73 | if (libBase->localebase != NULL) CloseLibrary(libBase->localebase); 74 | if (libBase->utilitybase != NULL) CloseLibrary(libBase->utilitybase); 75 | if (libBase->dosbase != NULL) CloseLibrary(libBase->dosbase); 76 | 77 | FreeMem((BYTE *)libBase - libBase->libnode.lib_NegSize, 78 | libBase->libnode.lib_NegSize + libBase->libnode.lib_PosSize); 79 | 80 | return NULL; 81 | 82 | #ifdef __AROS__ 83 | AROS_USERFUNC_EXIT 84 | #endif 85 | } 86 | 87 | #ifdef __AROS__ 88 | AROS_LH1(struct FileSysBoxBase *, LibOpen, 89 | AROS_LHA(ULONG, version, D0), 90 | struct FileSysBoxBase *, libBase, 1, FileSysBox) 91 | { 92 | AROS_LIBFUNC_INIT 93 | #else 94 | struct FileSysBoxBase *LibOpen( 95 | REG(a6, struct FileSysBoxBase *libBase)) 96 | { 97 | #endif 98 | 99 | #ifdef __AROS__ 100 | if (version > VERSION) return NULL; 101 | #endif 102 | /* Add any specific open code here 103 | Return 0 before incrementing OpenCnt to fail opening */ 104 | 105 | /* Add up the open count */ 106 | libBase->libnode.lib_OpenCnt++; 107 | 108 | return libBase; 109 | 110 | #ifdef __AROS__ 111 | AROS_LIBFUNC_EXIT 112 | #endif 113 | } 114 | 115 | #ifdef __AROS__ 116 | AROS_LH0(BPTR, LibClose, 117 | struct FileSysBoxBase *, libBase, 2, FileSysBox) 118 | { 119 | AROS_LIBFUNC_INIT 120 | #else 121 | BPTR LibClose( 122 | REG(a6, struct FileSysBoxBase *libBase)) 123 | { 124 | #endif 125 | 126 | /* Make sure to undo what open did */ 127 | 128 | /* Make the close count */ 129 | libBase->libnode.lib_OpenCnt--; 130 | 131 | return ZERO; 132 | 133 | #ifdef __AROS__ 134 | AROS_LIBFUNC_EXIT 135 | #endif 136 | } 137 | 138 | #ifdef __AROS__ 139 | AROS_LH0(BPTR, LibExpunge, 140 | struct FileSysBoxBase *, libBase, 3, FileSysBox) 141 | { 142 | AROS_LIBFUNC_INIT 143 | #else 144 | BPTR LibExpunge( 145 | REG(a6, struct FileSysBoxBase *libBase)) 146 | { 147 | #endif 148 | struct Library *SysBase = libBase->sysbase; 149 | BPTR result = ZERO; 150 | 151 | if (libBase->libnode.lib_OpenCnt == 0 && 152 | libBase->dlproc == NULL && 153 | libBase->lhproc == NULL) 154 | { 155 | result = libBase->seglist; 156 | 157 | /* Undo what the init code did */ 158 | if (libBase->localebase) { 159 | CloseLibrary(libBase->localebase); 160 | } 161 | CloseLibrary(libBase->utilitybase); 162 | CloseLibrary(libBase->dosbase); 163 | 164 | Remove((struct Node *)libBase); 165 | FreeMem((BYTE *)libBase - libBase->libnode.lib_NegSize, 166 | libBase->libnode.lib_NegSize + libBase->libnode.lib_PosSize); 167 | } else { 168 | libBase->libnode.lib_Flags |= LIBF_DELEXP; 169 | } 170 | 171 | return result; 172 | 173 | #ifdef __AROS__ 174 | AROS_LIBFUNC_EXIT 175 | #endif 176 | } 177 | 178 | #ifdef __AROS__ 179 | AROS_LH0(APTR, LibReserved, 180 | struct FileSysBoxBase *, libBase, 4, FileSysBox) 181 | { 182 | AROS_LIBFUNC_INIT 183 | #else 184 | APTR LibReserved( 185 | REG(a6, struct FileSysBoxBase *libBase)) 186 | { 187 | #endif 188 | 189 | return NULL; 190 | 191 | #ifdef __AROS__ 192 | AROS_LIBFUNC_EXIT 193 | #endif 194 | } 195 | 196 | #include "filesysbox_vectors.c" 197 | 198 | static const CONST_APTR LibInitTab[] = { 199 | (APTR)sizeof(struct FileSysBoxBase), 200 | LibVectors, 201 | NULL, 202 | LibInit 203 | }; 204 | 205 | static const struct Resident USED_VAR lib_res = { 206 | RTC_MATCHWORD, 207 | (struct Resident *)&lib_res, 208 | (APTR)(&lib_res + 1), 209 | RTF_AUTOINIT, 210 | VERSION, 211 | NT_LIBRARY, 212 | 0, 213 | (APTR)"filesysbox.library", 214 | (APTR)VSTRING, 215 | (APTR)LibInitTab 216 | }; 217 | 218 | -------------------------------------------------------------------------------- /include/pragmas/filesysbox_pragmas.h: -------------------------------------------------------------------------------- 1 | /* Automatically generated header (sfdc 1.12)! Do not edit! */ 2 | #ifndef PRAGMAS_FILESYSBOX_PRAGMAS_H 3 | #define PRAGMAS_FILESYSBOX_PRAGMAS_H 4 | 5 | /* 6 | ** $VER: filesysbox_pragmas.h $Id$ $Id$ 7 | ** 8 | ** Direct ROM interface (pragma) definitions. 9 | ** 10 | ** Copyright (c) 2001 Amiga, Inc. 11 | ** All Rights Reserved 12 | */ 13 | 14 | #if defined(LATTICE) || defined(__SASC) || defined(_DCC) 15 | #ifndef __CLIB_PRAGMA_LIBCALL 16 | #define __CLIB_PRAGMA_LIBCALL 17 | #endif /* __CLIB_PRAGMA_LIBCALL */ 18 | #else /* __MAXON__, __STORM__ or AZTEC_C */ 19 | #ifndef __CLIB_PRAGMA_AMICALL 20 | #define __CLIB_PRAGMA_AMICALL 21 | #endif /* __CLIB_PRAGMA_AMICALL */ 22 | #endif /* */ 23 | 24 | #if defined(__SASC_60) || defined(__STORM__) 25 | #ifndef __CLIB_PRAGMA_TAGCALL 26 | #define __CLIB_PRAGMA_TAGCALL 27 | #endif /* __CLIB_PRAGMA_TAGCALL */ 28 | #endif /* __MAXON__, __STORM__ or AZTEC_C */ 29 | 30 | #ifdef __CLIB_PRAGMA_LIBCALL 31 | #pragma libcall FileSysBoxBase FbxQueryMountMsg 1e 0802 32 | #endif /* __CLIB_PRAGMA_LIBCALL */ 33 | #ifdef __CLIB_PRAGMA_AMICALL 34 | #pragma amicall(FileSysBoxBase, 0x1e, FbxQueryMountMsg(a0,d0)) 35 | #endif /* __CLIB_PRAGMA_AMICALL */ 36 | #ifdef __CLIB_PRAGMA_LIBCALL 37 | #pragma libcall FileSysBoxBase FbxSetupFS 24 b0a9805 38 | #endif /* __CLIB_PRAGMA_LIBCALL */ 39 | #ifdef __CLIB_PRAGMA_AMICALL 40 | #pragma amicall(FileSysBoxBase, 0x24, FbxSetupFS(a0,a1,a2,d0,a3)) 41 | #endif /* __CLIB_PRAGMA_AMICALL */ 42 | #ifdef __CLIB_PRAGMA_LIBCALL 43 | #pragma libcall FileSysBoxBase FbxEventLoop 2a 801 44 | #endif /* __CLIB_PRAGMA_LIBCALL */ 45 | #ifdef __CLIB_PRAGMA_AMICALL 46 | #pragma amicall(FileSysBoxBase, 0x2a, FbxEventLoop(a0)) 47 | #endif /* __CLIB_PRAGMA_AMICALL */ 48 | #ifdef __CLIB_PRAGMA_LIBCALL 49 | #pragma libcall FileSysBoxBase FbxCleanupFS 30 801 50 | #endif /* __CLIB_PRAGMA_LIBCALL */ 51 | #ifdef __CLIB_PRAGMA_AMICALL 52 | #pragma amicall(FileSysBoxBase, 0x30, FbxCleanupFS(a0)) 53 | #endif /* __CLIB_PRAGMA_AMICALL */ 54 | #ifdef __CLIB_PRAGMA_LIBCALL 55 | #pragma libcall FileSysBoxBase FbxReturnMountMsg 36 10803 56 | #endif /* __CLIB_PRAGMA_LIBCALL */ 57 | #ifdef __CLIB_PRAGMA_AMICALL 58 | #pragma amicall(FileSysBoxBase, 0x36, FbxReturnMountMsg(a0,d0,d1)) 59 | #endif /* __CLIB_PRAGMA_AMICALL */ 60 | #ifdef __CLIB_PRAGMA_LIBCALL 61 | #pragma libcall FileSysBoxBase FbxFuseVersion 3c 00 62 | #endif /* __CLIB_PRAGMA_LIBCALL */ 63 | #ifdef __CLIB_PRAGMA_AMICALL 64 | #pragma amicall(FileSysBoxBase, 0x3c, FbxFuseVersion()) 65 | #endif /* __CLIB_PRAGMA_AMICALL */ 66 | #ifdef __CLIB_PRAGMA_LIBCALL 67 | #pragma libcall FileSysBoxBase FbxVersion 42 00 68 | #endif /* __CLIB_PRAGMA_LIBCALL */ 69 | #ifdef __CLIB_PRAGMA_AMICALL 70 | #pragma amicall(FileSysBoxBase, 0x42, FbxVersion()) 71 | #endif /* __CLIB_PRAGMA_AMICALL */ 72 | #ifdef __CLIB_PRAGMA_LIBCALL 73 | #pragma libcall FileSysBoxBase FbxSetSignalCallback 48 09803 74 | #endif /* __CLIB_PRAGMA_LIBCALL */ 75 | #ifdef __CLIB_PRAGMA_AMICALL 76 | #pragma amicall(FileSysBoxBase, 0x48, FbxSetSignalCallback(a0,a1,d0)) 77 | #endif /* __CLIB_PRAGMA_AMICALL */ 78 | #ifdef __CLIB_PRAGMA_LIBCALL 79 | #pragma libcall FileSysBoxBase FbxInstallTimerCallback 4e 09803 80 | #endif /* __CLIB_PRAGMA_LIBCALL */ 81 | #ifdef __CLIB_PRAGMA_AMICALL 82 | #pragma amicall(FileSysBoxBase, 0x4e, FbxInstallTimerCallback(a0,a1,d0)) 83 | #endif /* __CLIB_PRAGMA_AMICALL */ 84 | #ifdef __CLIB_PRAGMA_LIBCALL 85 | #pragma libcall FileSysBoxBase FbxUninstallTimerCallback 54 9802 86 | #endif /* __CLIB_PRAGMA_LIBCALL */ 87 | #ifdef __CLIB_PRAGMA_AMICALL 88 | #pragma amicall(FileSysBoxBase, 0x54, FbxUninstallTimerCallback(a0,a1)) 89 | #endif /* __CLIB_PRAGMA_AMICALL */ 90 | #ifdef __CLIB_PRAGMA_LIBCALL 91 | #pragma libcall FileSysBoxBase FbxSignalDiskChange 5a 801 92 | #endif /* __CLIB_PRAGMA_LIBCALL */ 93 | #ifdef __CLIB_PRAGMA_AMICALL 94 | #pragma amicall(FileSysBoxBase, 0x5a, FbxSignalDiskChange(a0)) 95 | #endif /* __CLIB_PRAGMA_AMICALL */ 96 | #ifdef __CLIB_PRAGMA_LIBCALL 97 | #pragma libcall FileSysBoxBase FbxCopyStringBSTRToC 60 09803 98 | #endif /* __CLIB_PRAGMA_LIBCALL */ 99 | #ifdef __CLIB_PRAGMA_AMICALL 100 | #pragma amicall(FileSysBoxBase, 0x60, FbxCopyStringBSTRToC(a0,a1,d0)) 101 | #endif /* __CLIB_PRAGMA_AMICALL */ 102 | #ifdef __CLIB_PRAGMA_LIBCALL 103 | #pragma libcall FileSysBoxBase FbxCopyStringCToBSTR 66 09803 104 | #endif /* __CLIB_PRAGMA_LIBCALL */ 105 | #ifdef __CLIB_PRAGMA_AMICALL 106 | #pragma amicall(FileSysBoxBase, 0x66, FbxCopyStringCToBSTR(a0,a1,d0)) 107 | #endif /* __CLIB_PRAGMA_AMICALL */ 108 | #ifdef __CLIB_PRAGMA_LIBCALL 109 | #pragma libcall FileSysBoxBase FbxQueryFS 6c 9802 110 | #endif /* __CLIB_PRAGMA_LIBCALL */ 111 | #ifdef __CLIB_PRAGMA_AMICALL 112 | #pragma amicall(FileSysBoxBase, 0x6c, FbxQueryFS(a0,a1)) 113 | #endif /* __CLIB_PRAGMA_AMICALL */ 114 | #ifdef __CLIB_PRAGMA_TAGCALL 115 | #ifdef __CLIB_PRAGMA_LIBCALL 116 | #pragma tagcall FileSysBoxBase FbxQueryFSTags 6c 9802 117 | #endif /* __CLIB_PRAGMA_LIBCALL */ 118 | #ifdef __CLIB_PRAGMA_AMICALL 119 | #pragma tagcall(FileSysBoxBase, 0x6c, FbxQueryFSTags(a0,a1)) 120 | #endif /* __CLIB_PRAGMA_AMICALL */ 121 | #endif /* __CLIB_PRAGMA_TAGCALL */ 122 | #ifdef __CLIB_PRAGMA_LIBCALL 123 | #pragma libcall FileSysBoxBase FbxGetSysTime 72 9802 124 | #endif /* __CLIB_PRAGMA_LIBCALL */ 125 | #ifdef __CLIB_PRAGMA_AMICALL 126 | #pragma amicall(FileSysBoxBase, 0x72, FbxGetSysTime(a0,a1)) 127 | #endif /* __CLIB_PRAGMA_AMICALL */ 128 | #ifdef __CLIB_PRAGMA_LIBCALL 129 | #pragma libcall FileSysBoxBase FbxGetUpTime 78 9802 130 | #endif /* __CLIB_PRAGMA_LIBCALL */ 131 | #ifdef __CLIB_PRAGMA_AMICALL 132 | #pragma amicall(FileSysBoxBase, 0x78, FbxGetUpTime(a0,a1)) 133 | #endif /* __CLIB_PRAGMA_AMICALL */ 134 | 135 | #endif /* PRAGMAS_FILESYSBOX_PRAGMAS_H */ 136 | -------------------------------------------------------------------------------- /src/filesysbox_vectors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #ifndef EXEC_EXEC_H 9 | #include 10 | #endif 11 | #ifndef DOS_DOS_H 12 | #include 13 | #endif 14 | #ifndef UTILITY_TAGITEM_H 15 | #include 16 | #endif 17 | #ifndef LIBRARIES_FILESYSBOX_H 18 | #include 19 | #endif 20 | 21 | #ifdef __AROS__ 22 | 23 | #include 24 | 25 | AROS_LD1(struct FileSysBoxBase *, LibOpen, 26 | AROS_LDA(ULONG, version, D0), 27 | struct FileSysBoxBase *, libBase, 1, FileSysBox); 28 | 29 | AROS_LD0(BPTR, LibClose, 30 | struct FileSysBoxBase *, libBase, 2, FileSysBox); 31 | 32 | AROS_LD0(BPTR, LibExpunge, 33 | struct FileSysBoxBase *, libBase, 3, FileSysBox); 34 | 35 | AROS_LD0(APTR, LibReserved, 36 | struct FileSysBoxBase *, libBase, 4, FileSysBox); 37 | 38 | AROS_LD2(APTR, FbxQueryMountMsg, 39 | AROS_LDA(struct Message *, msg, A0), 40 | AROS_LDA(LONG, attr, D0), 41 | struct FileSysBoxBase *, libBase, 5, FileSysBox); 42 | 43 | AROS_LD5(struct FbxFS *, FbxSetupFS, 44 | AROS_LDA(struct Message *, msg, A0), 45 | AROS_LDA(const struct TagItem *, tags, A1), 46 | AROS_LDA(const struct fuse_operations *, ops, A2), 47 | AROS_LDA(LONG, opssize, D0), 48 | AROS_LDA(APTR, udata, A3), 49 | struct FileSysBoxBase *, libBase, 6, FileSysBox); 50 | 51 | AROS_LD1(LONG, FbxEventLoop, 52 | AROS_LDA(struct FbxFS *, fs, A0), 53 | struct FileSysBoxBase *, libBase, 7, FileSysBox); 54 | 55 | AROS_LD1(void, FbxCleanupFS, 56 | AROS_LDA(struct FbxFS *, fs, A0), 57 | struct FileSysBoxBase *, libBase, 8, FileSysBox); 58 | 59 | AROS_LD3(void, FbxReturnMountMsg, 60 | AROS_LDA(struct Message *, msg, A0), 61 | AROS_LDA(SIPTR, r1, D0), 62 | AROS_LDA(SIPTR, r2, D1), 63 | struct FileSysBoxBase *, libBase, 9, FileSysBox); 64 | 65 | AROS_LD0(LONG, FbxFuseVersion, 66 | struct FileSysBoxBase *, libBase, 10, FileSysBox); 67 | 68 | AROS_LD0(LONG, FbxVersion, 69 | struct FileSysBoxBase *, libBase, 11, FileSysBox); 70 | 71 | AROS_LD3(void, FbxSetSignalCallback, 72 | AROS_LDA(struct FbxFS *, fs, A0), 73 | AROS_LDA(FbxSignalCallbackFunc, func, A1), 74 | AROS_LDA(ULONG, signals, D0), 75 | struct FileSysBoxBase *, libBase, 12, FileSysBox); 76 | 77 | AROS_LD3(struct FbxTimerCallbackData *, FbxInstallTimerCallback, 78 | AROS_LDA(struct FbxFS *, fs, A0), 79 | AROS_LDA(FbxTimerCallbackFunc, func, A1), 80 | AROS_LDA(ULONG, period, D0), 81 | struct FileSysBoxBase *, libBase, 13, FileSysBox); 82 | 83 | AROS_LD2(void, FbxUninstallTimerCallback, 84 | AROS_LDA(struct FbxFS *, fs, A0), 85 | AROS_LDA(struct FbxTimerCallbackData *, cb, A1), 86 | struct FileSysBoxBase *, libBase, 14, FileSysBox); 87 | 88 | AROS_LD1(void, FbxSignalDiskChange, 89 | AROS_LDA(struct FbxFS *, fs, A0), 90 | struct FileSysBoxBase *, libBase, 15, FileSysBox); 91 | 92 | AROS_LD3(void, FbxCopyStringBSTRToC, 93 | AROS_LDA(BSTR, src, A0), 94 | AROS_LDA(STRPTR, dst, A1), 95 | AROS_LDA(ULONG, size, D0), 96 | struct FileSysBoxBase *, libBase, 16, FileSysBox); 97 | 98 | AROS_LD3(void, FbxCopyStringCToBSTR, 99 | AROS_LDA(CONST_STRPTR, src, A0), 100 | AROS_LDA(BSTR, dst, A1), 101 | AROS_LDA(ULONG, size, D0), 102 | struct FileSysBoxBase *, libBase, 17, FileSysBox); 103 | 104 | AROS_LD2(void, FbxQueryFS, 105 | AROS_LDA(struct FbxFS *, fs, A0), 106 | AROS_LDA(const struct TagItem *, tags, A1), 107 | struct FileSysBoxBase *, libBase, 18, FileSysBox); 108 | 109 | AROS_LD2(void, FbxGetSysTime, 110 | AROS_LDA(struct FbxFS *, fs, A0), 111 | AROS_LDA(struct timeval *, tv, A1), 112 | struct FileSysBoxBase *, libBase, 19, FileSysBox); 113 | 114 | AROS_LD2(void, FbxGetUpTime, 115 | AROS_LDA(struct FbxFS *, fs, A0), 116 | AROS_LDA(struct timeval *, tv, A1), 117 | struct FileSysBoxBase *, libBase, 20, FileSysBox); 118 | 119 | #else 120 | 121 | #include 122 | 123 | struct FileSysBoxBase *LibOpen( 124 | REG(a6, struct FileSysBoxBase *libBase)); 125 | 126 | BPTR LibClose( 127 | REG(a6, struct FileSysBoxBase *libBase)); 128 | 129 | BPTR LibExpunge( 130 | REG(a6, struct FileSysBoxBase *libBase)); 131 | 132 | APTR LibReserved( 133 | REG(a6, struct FileSysBoxBase *libBase)); 134 | 135 | APTR FbxQueryMountMsg( 136 | REG(a0, struct Message *msg), 137 | REG(d0, LONG attr), 138 | REG(a6, struct FileSysBoxBase *libBase)); 139 | 140 | struct FbxFS *FbxSetupFS( 141 | REG(a0, struct Message *msg), 142 | REG(a1, const struct TagItem *tags), 143 | REG(a2, const struct fuse_operations *ops), 144 | REG(d0, LONG opssize), 145 | REG(a3, APTR udata), 146 | REG(a6, struct FileSysBoxBase *libBase)); 147 | 148 | LONG FbxEventLoop( 149 | REG(a0, struct FbxFS *fs), 150 | REG(a6, struct FileSysBoxBase *libBase)); 151 | 152 | void FbxCleanupFS( 153 | REG(a0, struct FbxFS * fs), 154 | REG(a6, struct FileSysBoxBase *libBase)); 155 | 156 | void FbxReturnMountMsg( 157 | REG(a0, struct Message *msg), 158 | REG(d0, SIPTR r1), 159 | REG(d1, SIPTR r2), 160 | REG(a6, struct FileSysBoxBase *libBase)); 161 | 162 | LONG FbxFuseVersion( 163 | REG(a6, struct FileSysBoxBase *libBase)); 164 | 165 | LONG FbxVersion( 166 | REG(a6, struct FileSysBoxBase *libBase)); 167 | 168 | void FbxSetSignalCallback( 169 | REG(a0, struct FbxFS *fs), 170 | REG(a1, FbxSignalCallbackFunc func), 171 | REG(d0, ULONG signals), 172 | REG(a6, struct FileSysBoxBase *libBase)); 173 | 174 | struct FbxTimerCallbackData *FbxInstallTimerCallback( 175 | REG(a0, struct FbxFS *fs), 176 | REG(a1, FbxTimerCallbackFunc func), 177 | REG(d0, ULONG period), 178 | REG(a6, struct FileSysBoxBase *libBase)); 179 | 180 | void FbxUninstallTimerCallback( 181 | REG(a0, struct FbxFS *fs), 182 | REG(a1, struct FbxTimerCallbackData *cb), 183 | REG(a6, struct FileSysBoxBase *libBase)); 184 | 185 | void FbxSignalDiskChange( 186 | REG(a0, struct FbxFS *fs), 187 | REG(a6, struct FileSysBoxBase *libBase)); 188 | 189 | void FbxCopyStringBSTRToC( 190 | REG(a0, BSTR src), 191 | REG(a1, STRPTR dst), 192 | REG(d0, ULONG size), 193 | REG(a6, struct FileSysBoxBase *libBase)); 194 | 195 | void FbxCopyStringCToBSTR( 196 | REG(a0, CONST_STRPTR src), 197 | REG(a1, BSTR dst), 198 | REG(d0, ULONG size), 199 | REG(a6, struct FileSysBoxBase *libBase)); 200 | 201 | void FbxQueryFS( 202 | REG(a0, struct FbxFS *fs), 203 | REG(a1, const struct TagItem *tags), 204 | REG(a6, struct FileSysBoxBase *libBase)); 205 | 206 | void FbxGetSysTime( 207 | REG(a0, struct FbxFS *fs), 208 | REG(a1, struct timeval *tv), 209 | REG(a6, struct FileSysBoxBase *libBase)); 210 | 211 | void FbxGetUpTime( 212 | REG(a0, struct FbxFS *fs), 213 | REG(a1, struct timeval *tv), 214 | REG(a6, struct FileSysBoxBase *libBase)); 215 | 216 | #endif 217 | 218 | -------------------------------------------------------------------------------- /src/volume.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | #include 15 | 16 | static APTR Fbx_init(struct FbxFS *fs, struct fuse_conn_info *conn) 17 | { 18 | ODEBUGF("Fbx_init(%#p, %#p)\n", fs, conn); 19 | 20 | if (FSOP init) 21 | { 22 | fs->initret = FSOP init(conn, &fs->fcntx); 23 | return fs->initret; 24 | } 25 | else 26 | { 27 | const char *devname = (const char *)BADDR(fs->devnode->dn_Name) + 1; 28 | #ifdef ENABLE_CHARSET_CONVERSION 29 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) 30 | FbxLocalToUTF8(fs, conn->volume_name, devname, CONN_VOLUME_NAME_BYTES); 31 | else 32 | strlcpy(conn->volume_name, devname, CONN_VOLUME_NAME_BYTES); 33 | #else 34 | /* FIXME: No UTF-8 validity check */ 35 | FbxStrlcpy(fs, conn->volume_name, devname, CONN_VOLUME_NAME_BYTES); 36 | #endif 37 | return (APTR)TRUE; 38 | } 39 | } 40 | 41 | static void Fbx_destroy(struct FbxFS *fs, APTR x) 42 | { 43 | ODEBUGF("Fbx_destroy(%#p, %#p)\n", fs, x); 44 | 45 | if (FSOP destroy) FSOP destroy(x, &fs->fcntx); 46 | } 47 | 48 | struct FbxVolume *FbxSetupVolume(struct FbxFS *fs) { 49 | struct Library *SysBase = fs->sysbase; 50 | #ifndef NODEBUG 51 | struct Library *DOSBase = fs->dosbase; 52 | #endif 53 | struct fuse_conn_info *conn = &fs->conn; 54 | APTR initret; 55 | int error, i, rc; 56 | struct FbxVolume *vol; 57 | struct statvfs st; 58 | struct fbx_stat statbuf; 59 | #ifdef ENABLE_CHARSET_CONVERSION 60 | char advolname[FBX_MAX_NAME]; 61 | #endif 62 | const char *volname; 63 | 64 | DEBUGF("FbxSetupVolume(%#p)\n", fs); 65 | 66 | if (OKVOLUME(fs->currvol)) { 67 | return fs->currvol; 68 | } 69 | 70 | if (fs->inhibit) { 71 | return fs->currvol = NULL; 72 | } 73 | 74 | bzero(conn, sizeof(*conn)); 75 | 76 | initret = Fbx_init(fs, conn); 77 | if (initret == (APTR)-2) { 78 | // error setting up resources for accessing volume 79 | debugf("fbx fs failed to open resources for volume\n"); 80 | return fs->currvol = (APTR)-2; 81 | } else if (initret == (APTR)-1) { 82 | // broken on-disk layout (or not formatted) 83 | return fs->currvol = (APTR)-1; 84 | } else if (initret == NULL) { 85 | // no disk in drive 86 | return fs->currvol = NULL; 87 | } 88 | 89 | DEBUGF("FbxSetupVolume: conn.volume_name '%s'\n", conn->volume_name); 90 | 91 | volname = conn->volume_name; 92 | #ifdef ENABLE_CHARSET_CONVERSION 93 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 94 | if (FbxUTF8ToLocal(fs, advolname, volname, FBX_MAX_NAME) >= FBX_MAX_NAME) { 95 | Fbx_destroy(fs, fs->initret); 96 | return NULL; 97 | } 98 | volname = advolname; 99 | } 100 | #endif 101 | 102 | // if statfs fails, abort. 103 | error = Fbx_statfs(fs, "/", &st); 104 | if (error) { 105 | DEBUGF("FbxSetupVolume: statfs failed (not formatted ?) err %d\n", error); 106 | Fbx_destroy(fs, fs->initret); 107 | return FALSE; 108 | } 109 | 110 | error = Fbx_getattr(fs, "/", &statbuf); 111 | if (error) { 112 | DEBUGF("FbxSetupVolume: stat on root directory failed err %d\n", error); 113 | Fbx_destroy(fs, fs->initret); 114 | return FALSE; 115 | } 116 | 117 | vol = AllocFbxVolume(); 118 | if (vol == NULL) { 119 | Fbx_destroy(fs, fs->initret); 120 | return NULL; 121 | } 122 | 123 | vol->dl.dl_Type = DLT_VOLUME; 124 | vol->dl.dl_Task = fs->fsport; 125 | vol->dl.dl_DiskType = fs->dostype; 126 | #if defined(__AROS__) && defined(AROS_FAST_BSTR) 127 | vol->dl.dl_Name = (STRPTR)vol->volname; 128 | #else 129 | vol->dl.dl_Name = MKBADDR(&vol->volnamelen); 130 | #endif 131 | 132 | FbxTimeSpec2DS(fs, &statbuf.st_ctim, &vol->dl.dl_VolumeDate); 133 | #ifdef ENABLE_CHARSET_CONVERSION 134 | strlcpy(vol->volname, volname, CONN_VOLUME_NAME_BYTES); 135 | #else 136 | FbxStrlcpy(fs, vol->volname, volname, CONN_VOLUME_NAME_BYTES); 137 | #endif 138 | vol->volnamelen = strlen(vol->volname); 139 | 140 | vol->fs = fs; 141 | vol->writeprotect = FALSE; 142 | vol->vflags = 0; 143 | 144 | NEWMINLIST(&vol->unres_notifys); 145 | NEWMINLIST(&vol->locklist); 146 | NEWMINLIST(&vol->notifylist); 147 | for (i = 0; i < ENTRYHASHSIZE; i++) { 148 | NEWMINLIST(&vol->entrytab[i]); 149 | } 150 | 151 | if (st.f_flag & ST_CASE_SENSITIVE) { 152 | vol->vflags |= FBXVF_CASE_SENSITIVE; 153 | } 154 | 155 | if (st.f_flag & ST_RDONLY) { 156 | vol->vflags |= FBXVF_READ_ONLY; 157 | } 158 | 159 | // add volume to doslist 160 | rc = FbxAsyncAddVolume(fs, vol); 161 | if (!rc) { 162 | DEBUGF("FbxSetupVolume: NBM_ADDDOSENTRY failed (name collision ?) err %d\n", (int)IoErr()); 163 | Fbx_destroy(fs, fs->initret); 164 | FreeFbxVolume(vol); 165 | return NULL; 166 | } 167 | 168 | fs->currvol = vol; 169 | 170 | // tell input.device there was a change 171 | FbxNotifyDiskChange(fs, IECLASS_DISKINSERTED); 172 | 173 | DEBUGF("FbxSetupVolume: Volume %#p set up OK.\n", vol); 174 | 175 | return vol; 176 | } 177 | 178 | void FbxCleanupVolume(struct FbxFS *fs) { 179 | struct Library *SysBase = fs->sysbase; 180 | struct FbxVolume *vol = fs->currvol; 181 | 182 | // do nothing if we don't have a volume 183 | if (NOVOLUME(vol)) { 184 | fs->currvol = NULL; 185 | return; 186 | } 187 | 188 | // only notify about disk removal if we have a bad volume. 189 | if (BADVOLUME(vol)) { 190 | fs->currvol = NULL; 191 | // notify about disk removal 192 | FbxNotifyDiskChange(fs, IECLASS_DISKREMOVED); 193 | return; 194 | } 195 | 196 | struct MinNode *chain, *succ; 197 | chain = vol->locklist.mlh_Head; 198 | while ((succ = chain->mln_Succ) != NULL) { 199 | struct FbxLock *lock = FSLOCKFROMVOLUMECHAIN(chain); 200 | 201 | if (lock->info != NULL) { 202 | struct FbxEntry *e = lock->entry; 203 | Fbx_release(fs, e->path, lock->info); 204 | FreeFuseFileInfo(fs, lock->info); 205 | lock->info = NULL; 206 | } 207 | 208 | chain = succ; 209 | } 210 | 211 | // Make sure that dirty data is on disk before destroying 212 | FbxFlushAll(fs); 213 | 214 | Fbx_destroy(fs, fs->initret); 215 | 216 | if (IsMinListEmpty(&vol->locklist) && 217 | IsMinListEmpty(&vol->notifylist)) 218 | { 219 | // Remove and free if no locks are pending 220 | FbxAsyncRemFreeVolume(fs, vol); 221 | } else { 222 | // Remove and add to list if there are locks pending 223 | FbxAsyncRemVolume(fs, vol); 224 | AddTail((struct List *)&fs->volumelist, (struct Node *)&vol->fschain); 225 | } 226 | 227 | fs->currvol = NULL; 228 | 229 | // notify about disk removal 230 | FbxNotifyDiskChange(fs, IECLASS_DISKREMOVED); 231 | 232 | // reset update timeouts 233 | FbxSetModifyState(fs, 0); 234 | } 235 | 236 | -------------------------------------------------------------------------------- /src/doslist.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #include "filesysbox_internal.h" 9 | #include 10 | #include 11 | 12 | struct FbxAsyncMsg { 13 | struct Message msg; 14 | struct FbxFS *fs; 15 | struct FbxVolume *vol; 16 | int cmd; 17 | char name[]; 18 | }; 19 | 20 | enum { 21 | FBX_ASYNC_ADD, 22 | FBX_ASYNC_REMOVE, 23 | FBX_ASYNC_REMOVE_FREE, 24 | FBX_ASYNC_RENAME 25 | }; 26 | 27 | #ifdef __AROS__ 28 | static AROS_UFH3(int, FbxDosListProc, 29 | AROS_UFHA(STRPTR, argstr, A0), 30 | AROS_UFHA(ULONG, arglen, D0), 31 | AROS_UFHA(struct Library *, SysBase, A6) 32 | ) 33 | { 34 | AROS_USERFUNC_INIT 35 | #else 36 | static int FbxDosListProc(void) { 37 | struct Library *SysBase = *(struct Library **)4; 38 | #endif 39 | struct FileSysBoxBase *libBase; 40 | struct Library *DOSBase; 41 | struct Process *proc; 42 | struct MsgPort *port; 43 | #ifndef __AROS__ 44 | struct Message *msg; 45 | #endif 46 | struct FbxAsyncMsg *async_msg; 47 | 48 | proc = (struct Process *)FindTask(NULL); 49 | port = &proc->pr_MsgPort; 50 | 51 | #ifdef __AROS__ 52 | libBase = proc->pr_Task.tc_UserData; 53 | #else 54 | WaitPort(port); 55 | msg = GetMsg(port); 56 | libBase = (struct FileSysBoxBase *)msg->mn_Node.ln_Name; 57 | #endif 58 | DOSBase = libBase->dosbase; 59 | 60 | for (;;) { 61 | Wait(SIGBREAKF_CTRL_C | (1UL << port->mp_SigBit)); 62 | 63 | if (!IsListEmpty(&port->mp_MsgList)) { 64 | LockDosList(LDF_ALL|LDF_WRITE); 65 | while ((async_msg = (struct FbxAsyncMsg *)GetMsg(port)) != NULL) { 66 | struct FbxVolume *vol = async_msg->vol; 67 | int cmd = async_msg->cmd; 68 | switch (cmd) { 69 | case FBX_ASYNC_ADD: 70 | AddDosEntry(&vol->dol); 71 | break; 72 | case FBX_ASYNC_REMOVE: 73 | RemDosEntry(&vol->dol); 74 | break; 75 | case FBX_ASYNC_REMOVE_FREE: 76 | if (RemDosEntry(&vol->dol)) 77 | FreeFbxVolume(vol); 78 | break; 79 | case FBX_ASYNC_RENAME: 80 | if (RemDosEntry(&vol->dol)) { 81 | #ifdef ENABLE_CHARSET_CONVERSION 82 | strlcpy(vol->volname, async_msg->name, CONN_VOLUME_NAME_BYTES); 83 | #else 84 | FbxStrlcpy(async_msg->fs, vol->volname, async_msg->name, CONN_VOLUME_NAME_BYTES); 85 | #endif 86 | vol->volnamelen = strlen(vol->volname); 87 | AddDosEntry(&vol->dol); 88 | } 89 | break; 90 | } 91 | FreeMem(async_msg, async_msg->msg.mn_Length); 92 | } 93 | UnLockDosList(LDF_ALL|LDF_WRITE); 94 | } 95 | 96 | if (libBase->dlproc_refcount == 0) { 97 | ObtainSemaphore(&libBase->procsema); 98 | if (libBase->dlproc_refcount == 0) 99 | break; 100 | ReleaseSemaphore(&libBase->procsema); 101 | } 102 | } 103 | 104 | while ((async_msg = (struct FbxAsyncMsg *)GetMsg(port)) != NULL) 105 | FreeMem(async_msg, async_msg->msg.mn_Length); 106 | 107 | Forbid(); 108 | libBase->dlproc = NULL; 109 | ReleaseSemaphore(&libBase->procsema); 110 | return RETURN_OK; 111 | 112 | #ifdef __AROS__ 113 | AROS_USERFUNC_EXIT 114 | #endif 115 | } 116 | 117 | struct Process *StartDosListProc(struct FileSysBoxBase *libBase) { 118 | struct Library *DOSBase = libBase->dosbase; 119 | struct Process *dlproc; 120 | 121 | dlproc = CreateNewProcTags( 122 | NP_Entry, (IPTR)FbxDosListProc, 123 | #ifdef __AROS__ 124 | NP_UserData, (IPTR)libBase, 125 | #endif 126 | NP_StackSize, 4096, 127 | NP_Name, (IPTR)"FileSysBox DosList handler", 128 | NP_Priority, 15, 129 | NP_Cli, FALSE, 130 | NP_WindowPtr, -1, 131 | NP_CopyVars, FALSE, 132 | NP_CurrentDir, 0, 133 | NP_HomeDir, 0, 134 | NP_Error, 0, 135 | NP_CloseError, FALSE, 136 | NP_Input, 0, 137 | NP_CloseInput, FALSE, 138 | NP_Output, 0, 139 | NP_CloseOutput, FALSE, 140 | NP_ConsoleTask, 0, 141 | TAG_END); 142 | 143 | #ifndef __AROS__ 144 | if (dlproc != NULL) { 145 | struct Library *SysBase = libBase->sysbase; 146 | static struct Message msg; 147 | 148 | bzero(&msg, sizeof(msg)); 149 | msg.mn_Node.ln_Type = NT_MESSAGE; 150 | msg.mn_Node.ln_Name = (char *)libBase; 151 | msg.mn_Length = sizeof(msg); 152 | PutMsg(&dlproc->pr_MsgPort, &msg); 153 | } 154 | #endif 155 | 156 | return dlproc; 157 | } 158 | 159 | static int FbxAsyncDosListCmd(struct FbxFS *fs, struct FbxVolume *vol, int cmd, const char *name) { 160 | struct Library *SysBase = fs->sysbase; 161 | struct Library *DOSBase = fs->dosbase; 162 | struct DosList *dl = NULL; 163 | int i, res; 164 | 165 | if (vol == NULL) 166 | return FALSE; 167 | 168 | if (IsListEmpty(&fs->dlproc_port->mp_MsgList)) { 169 | for (i = 0; i < 10; i++) { 170 | dl = AttemptLockDosList(LDF_ALL|LDF_WRITE); 171 | if (dl != NULL) 172 | break; 173 | Delay(10); 174 | } 175 | } 176 | 177 | if (dl != NULL) { 178 | switch (cmd) { 179 | case FBX_ASYNC_ADD: 180 | res = AddDosEntry(&vol->dol); 181 | break; 182 | case FBX_ASYNC_REMOVE: 183 | res = RemDosEntry(&vol->dol); 184 | break; 185 | case FBX_ASYNC_REMOVE_FREE: 186 | if ((res = RemDosEntry(&vol->dol))) 187 | FreeFbxVolume(vol); 188 | break; 189 | case FBX_ASYNC_RENAME: 190 | if ((res = RemDosEntry(&vol->dol))) { 191 | FbxStrlcpy(fs, vol->volname, name, CONN_VOLUME_NAME_BYTES); 192 | vol->volnamelen = strlen(vol->volname); 193 | res = AddDosEntry(&vol->dol); 194 | } 195 | break; 196 | default: 197 | res = FALSE; 198 | break; 199 | } 200 | UnLockDosList(LDF_ALL|LDF_WRITE); 201 | } else { 202 | struct FbxAsyncMsg *msg; 203 | int len; 204 | 205 | len = sizeof(struct FbxAsyncMsg); 206 | if (name != NULL) len += strlen(name) + 1; 207 | 208 | for (i = 0; i < 10; i++) { 209 | msg = AllocMem(len, MEMF_PUBLIC|MEMF_CLEAR); 210 | if (msg != NULL) 211 | break; 212 | Delay(10); 213 | } 214 | if (msg != NULL) { 215 | msg->msg.mn_Node.ln_Type = NT_MESSAGE; 216 | msg->msg.mn_Length = len; 217 | msg->fs = fs; 218 | msg->vol = vol; 219 | msg->cmd = cmd; 220 | if (name != NULL) strcpy(msg->name, name); 221 | PutMsg(fs->dlproc_port, &msg->msg); 222 | res = TRUE; 223 | } else { 224 | res = FALSE; 225 | } 226 | } 227 | 228 | return res; 229 | } 230 | 231 | int FbxAsyncAddVolume(struct FbxFS *fs, struct FbxVolume *vol) { 232 | return FbxAsyncDosListCmd(fs, vol, FBX_ASYNC_ADD, NULL); 233 | } 234 | 235 | int FbxAsyncRemVolume(struct FbxFS *fs, struct FbxVolume *vol) { 236 | return FbxAsyncDosListCmd(fs, vol, FBX_ASYNC_REMOVE, NULL); 237 | } 238 | 239 | int FbxAsyncRemFreeVolume(struct FbxFS *fs, struct FbxVolume *vol) { 240 | return FbxAsyncDosListCmd(fs, vol, FBX_ASYNC_REMOVE_FREE, NULL); 241 | } 242 | 243 | int FbxAsyncRenameVolume(struct FbxFS *fs, struct FbxVolume *vol, const char *name) { 244 | return FbxAsyncDosListCmd(fs, vol, FBX_ASYNC_RENAME, name); 245 | } 246 | 247 | -------------------------------------------------------------------------------- /releasenotes: -------------------------------------------------------------------------------- 1 | filesysbox.library 53.1 (16.7.2015) 2 | 3 | - First released version. 4 | 5 | 6 | filesysbox.library 53.2 (6.8.2015) 7 | 8 | - FBXQMM_MOUNT_CONTROL doesn't skip the first character of the Control string 9 | on AROS any more. 10 | 11 | 12 | filesysbox.library 53.3 (13.8.2015) 13 | 14 | - CHECKWRITABLE() now also checks if the FBXVF_READ_ONLY flag is set. 15 | 16 | - Removed code for opening and closing of intuition.library since this library 17 | was not used anywhere. 18 | 19 | 20 | filesysbox.library 53.4 (23.8.2015) 21 | 22 | - Moved the opening and closing of dos.library and utility.library to the 23 | libInit() and libExpunge() functions. 24 | 25 | - Fixed error reporting in FbxWriteFile(). 26 | 27 | - Rewrote and simplified comment handling in FbxExamineAll(). 28 | 29 | - FbxExamineAll() now also stops scanning on any error encountered. 30 | 31 | 32 | filesysbox.library 53.5 (26.8.2015) 33 | 34 | - FbxExamineAll() now only returns DOSTRUE when there are more entries 35 | available. 36 | 37 | - Fixed a bad pointer access in FbxExamineAllEnd() introduced by a change in 38 | the last version. 39 | 40 | 41 | filesysbox.library 53.6 (26.12.2015) 42 | 43 | - FbxSameLock() now returns DOSTRUE if entry pointers are the same. 44 | 45 | - Removed the now useless path comparison in FbxSameLock(). 46 | 47 | 48 | filesysbox.library 53.7 (26.4.2018) 49 | 50 | - Got rid of all the GetXxxBase macros. 51 | 52 | - Fixed an out of bounds array access in FbxUpdatePaths() which would result 53 | in memory after the FbxFS struct being trashed. 54 | 55 | 56 | filesysbox.library 54.0 (22.12.2022) 57 | 58 | - Added timezone conversion code using locale.library. 59 | 60 | - Calculate a path hash for fib_DiskKey unless FBXF_USE_INO flag is set. 61 | 62 | - Added FBXF_USE_FILL_DIR_STAT flag to avoid unnecessary getattr() calls for 63 | filesystems like ssh2-handler that already provide all the stat data in 64 | readdir(). 65 | 66 | - Don't treat ENOSYS return value from FbxSetAmigaProtectionFlags() as an 67 | error. 68 | 69 | - Rewrote the FbxFillInfoData() function and made it set id_BytesPerBlock to 70 | 512 instead of zero if a volume is not available. 71 | 72 | - Modified path handling for Ext2FileSystem which only accepts "/" as path 73 | argument for the file system root directory and not "". 74 | 75 | - Rewrote FbxReturnMountMsg() using ReplyPkt() and added a NULL msg safety 76 | check. 77 | 78 | - Added some more validity checks when reading FSSM from device node in 79 | FbxSetupFS(). 80 | 81 | - Added validity checks in code for getting FSSM in FbxQueryMountMsg(). 82 | 83 | - Changed CHECKVOLUME() macro to return ERROR_NOT_A_DOS_DISK instead of 84 | ERROR_OBJECT_IN_USE when the filesystem is inhibited. 85 | 86 | - Added semaphore protection in FbxHandleTimerEvent(). 87 | 88 | - Added the FbxQueryFS() and FbxQueryFSTags() functions. 89 | 90 | - Added the FbxGetSysTime() function. 91 | 92 | 93 | filesysbox.library 54.1 (14.1.2023) 94 | 95 | - A rename operation with exactly the same source and destination is now 96 | treated as a no-op and returns success rather than ERROR_OBJECT_EXISTS. 97 | 98 | - Rename operations where the the only change is in letter casing (e.g. 99 | "rename tmp TMP") no longer fail with ERROR_OBJECT_EXISTS on case 100 | insensitive file system implementations. 101 | 102 | - Advance the file position in FSWrite() also if write() returns a lower 103 | number of bytes written than was specified. 104 | 105 | - Implemented the same charset conversion system that is used in the latest 106 | AmigaOS 4 filesysbox versions. Internally filesysbox still uses UTF-8 for 107 | all strings and conversion only happens when strings are passed to or from 108 | the AmigaDOS API. In order for the conversion to be reversible any UTF-8 109 | characters that do not have an equivalent in the local charset will be 110 | converted into URL-style escape sequences where the character is specified 111 | as a base32 encoded character sequence preceded by a percent symbol. 112 | 113 | 114 | filesysbox.library 54.2 (16.1.2023) 115 | 116 | - Fixed support for codesets other than ISO-8859-1/latin-1 (was not working 117 | before due to size and attributes parameters being switched around in the 118 | AllocMem() call). 119 | 120 | - Now ignores the ".language" extension when looking for a codeset based on 121 | loc_LanguageName. 122 | 123 | - UTF-8 to local charset conversion now uses an AVL tree instead of iterating 124 | over the maptable array to find a match. 125 | 126 | - Added experimental ACTION_DIE packet support. 127 | 128 | 129 | filesysbox.library 54.3 (18.1.2023) 130 | 131 | - AllocFuseFileInfo() did not clear the allocated fuse_file_info structure 132 | which resulted in randomly occurring bugs like otherwise legal ACTION_SEEK 133 | packets failing with ERROR_ACTION_NOT_KNOWN if the nonseekable flag happened 134 | to be set. This has now been fixed by explicitly clearing the memory before 135 | it is used. 136 | 137 | - Changed to use ULONGs for the uptime timestamps used in FbxEventLoop() to 138 | save some CPU cycles. 139 | 140 | - Rewrote the FbxExamineAll() function to not make assumptions about the sizes 141 | of the various ExAllData fields. 142 | 143 | 144 | filesysbox.library 54.4 (23.6.2023) 145 | 146 | - When setting fib_Size/ed_Size clamp file size to (INT32_MAX-1) if the field 147 | is 32-bit (LONG/ULONG). 148 | 149 | - Fixed a memory leak in the ExNext directory scanning implementation (nodes 150 | are removed from the dirdatalist but not freed) that was already there in 151 | the 0.730 version of the library. 152 | 153 | - Implemented a lock handler process to allow file systems to be unmounted 154 | even if there are outstanding locks/notifications. 155 | 156 | - AmigaOS 3 versions are now compiled with -mregparm enabling the use of 157 | registers d0/d1 and a0/a1 for parameter passing in internal function 158 | calls. 159 | 160 | 161 | filesysbox.library 54.5 (21.7.2023) 162 | 163 | - Added the FbxGetUpTime() function to the jumptable. 164 | 165 | - Made FbxLockName2Path() return FALSE for any paths containing "." or ".." as 166 | a file or directory name. 167 | 168 | - AmigaOS 3: Added a version compiled for the 68060 CPU. 169 | 170 | 171 | filesysbox.library 54.6 (3.6.2025) 172 | 173 | - AmigaOS 3: Added support for ACTION_CHANGE_FILE_POSITION64, 174 | ACTION_CHANGE_FILE_SIZE64, ACTION_GET_FILE_POSITION64 and 175 | ACTION_GET_FILE_SIZE64 packets. 176 | 177 | - ACTION_SEEK and ACTION_SET_FILE_SIZE now fail with ERROR_OBJECT_TOO_LARGE if 178 | the return value is too large to fit into dp_Res1. 179 | 180 | 181 | filesysbox.library 54.7 (10.6.2025) 182 | 183 | - Fixed an infinite recursion bug in the new V54.6 ACTION_SET_FILE_SIZE 184 | implementation caused by the FbxSetFileSize() function calling itself 185 | instead of FbxSetFileSize64() as it was supposed to. 186 | 187 | -------------------------------------------------------------------------------- /src/fsopen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Filesysbox filesystem layer/framework 3 | * 4 | * Copyright (c) 2008-2011 Leif Salomonsson [dev blubbedev net] 5 | * Copyright (c) 2013-2025 Fredrik Wikstrom [fredrik a500 org] 6 | * 7 | * This library is released under AROS PUBLIC LICENSE 1.1 8 | * See the file LICENSE.APL 9 | */ 10 | 11 | #include "filesysbox_internal.h" 12 | #include "fuse_stubs.h" 13 | #include 14 | #include 15 | 16 | static int Fbx_create(struct FbxFS *fs, const char *path, mode_t mode, struct fuse_file_info *fi) 17 | { 18 | ODEBUGF("Fbx_create(%#p, '%s', 0%o, %#p)\n", fs, path, mode, fi); 19 | 20 | return FSOP create(path, mode, fi, &fs->fcntx); 21 | } 22 | 23 | static int Fbx_mknod(struct FbxFS *fs, const char *path, mode_t mode, dev_t dev) 24 | { 25 | ODEBUGF("Fbx_mknod(%#p, '%s', 0%o, %#x)\n", fs, path, mode, dev); 26 | 27 | return FSOP mknod(path, mode, dev, &fs->fcntx); 28 | } 29 | 30 | static int Fbx_truncate(struct FbxFS *fs, const char *path, QUAD size) 31 | { 32 | ODEBUGF("Fbx_truncate(%#p, '%s', %lld)\n", fs, path, size); 33 | 34 | return FSOP truncate(path, size, &fs->fcntx); 35 | } 36 | 37 | static int FbxCreateOpenLock(struct FbxFS *fs, struct FileHandle *fh, struct FbxLock *lock, mode_t mode) { 38 | struct Library *SysBase = fs->sysbase; 39 | int error; 40 | 41 | PDEBUGF("FbxCreateOpenLock(%#p, %#p, %#p, 0%o)\n", fs, fh, lock, mode); 42 | 43 | CHECKLOCK(lock, DOSFALSE); 44 | 45 | if (lock->fsvol != fs->currvol) { 46 | fs->r2 = ERROR_NO_DISK; 47 | return DOSFALSE; 48 | } 49 | 50 | if (lock->entry->type != ETYPE_FILE) { 51 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 52 | return DOSFALSE; 53 | } 54 | 55 | if (lock->info != NULL) { 56 | fs->r2 = ERROR_OBJECT_IN_USE; 57 | return DOSFALSE; 58 | } 59 | 60 | lock->info = AllocFuseFileInfo(fs); 61 | if (lock->info == NULL) { 62 | fs->r2 = ERROR_NO_FREE_STORE; 63 | return DOSFALSE; 64 | } 65 | bzero(lock->info, sizeof(*lock->info)); 66 | 67 | if (fs->currvol->vflags & FBXVF_READ_ONLY) 68 | lock->info->flags = O_RDONLY; 69 | else 70 | lock->info->flags = O_RDWR; 71 | 72 | error = Fbx_create(fs, lock->entry->path, mode, lock->info); 73 | if (error) { 74 | FreeFuseFileInfo(fs, lock->info); 75 | lock->info = NULL; 76 | fs->r2 = FbxFuseErrno2Error(error); 77 | return DOSFALSE; 78 | } 79 | 80 | lock->fh = fh; 81 | fh->fh_Arg1 = (SIPTR)MKBADDR(lock); 82 | 83 | fs->r2 = 0; 84 | return DOSTRUE; 85 | } 86 | 87 | int FbxOpenFile(struct FbxFS *fs, struct FileHandle *fh, struct FbxLock *lock, 88 | const char *name, int mode) 89 | { 90 | struct FbxEntry *e; 91 | int error, truncate = FALSE; 92 | int lockmode = SHARED_LOCK; 93 | struct fbx_stat statbuf; 94 | struct FbxLock *lock2 = NULL; 95 | int exists; 96 | char fullpath[FBX_MAX_PATH]; 97 | #ifdef ENABLE_CHARSET_CONVERSION 98 | char fsname[FBX_MAX_NAME]; 99 | #endif 100 | 101 | DEBUGF("FbxOpenFile(%#p, %#p, %#p, '%s', %d)\n", fs, fh, lock, name, mode); 102 | 103 | CHECKVOLUME(DOSFALSE); 104 | 105 | if (lock != NULL) { 106 | CHECKLOCK(lock, DOSFALSE); 107 | 108 | if (lock->fsvol != fs->currvol) { 109 | fs->r2 = ERROR_NO_DISK; 110 | return DOSFALSE; 111 | } 112 | } 113 | 114 | #ifdef ENABLE_CHARSET_CONVERSION 115 | if (fs->fsflags & FBXF_ENABLE_UTF8_NAMES) { 116 | if (FbxLocalToUTF8(fs, fsname, name, FBX_MAX_NAME) >= FBX_MAX_NAME) { 117 | fs->r2 = ERROR_LINE_TOO_LONG; 118 | return DOSFALSE; 119 | } 120 | name = fsname; 121 | } 122 | #else 123 | CHECKSTRING(name, DOSFALSE); 124 | #endif 125 | 126 | if (!FbxLockName2Path(fs, lock, name, fullpath)) { 127 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 128 | return DOSFALSE; 129 | } 130 | 131 | e = FbxFindEntry(fs, fullpath); 132 | if (e != NULL) { 133 | if (e->type == ETYPE_DIR) { 134 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 135 | return DOSFALSE; 136 | } 137 | exists = TRUE; 138 | } else { 139 | error = Fbx_getattr(fs, fullpath, &statbuf); 140 | if (error == -ENOENT) { 141 | exists = FALSE; 142 | } else if (error == 0) { 143 | if (S_ISLNK(statbuf.st_mode)) { 144 | fs->r2 = ERROR_IS_SOFT_LINK; 145 | return DOSFALSE; 146 | } else if (!S_ISREG(statbuf.st_mode)) { 147 | fs->r2 = ERROR_OBJECT_WRONG_TYPE; 148 | return DOSFALSE; 149 | } 150 | exists = TRUE; 151 | } else { 152 | fs->r2 = FbxFuseErrno2Error(error); 153 | return DOSFALSE; 154 | } 155 | } 156 | 157 | switch (mode) { 158 | case MODE_OLDFILE: 159 | if (!exists) { 160 | fs->r2 = ERROR_OBJECT_NOT_FOUND; 161 | return DOSFALSE; 162 | } 163 | break; 164 | case MODE_NEWFILE: 165 | lockmode = EXCLUSIVE_LOCK; 166 | if (e != NULL && !IsMinListEmpty(&e->locklist)) { 167 | /* locked before, a no go as we need exclusive */ 168 | fs->r2 = ERROR_OBJECT_IN_USE; 169 | return DOSFALSE; 170 | } 171 | if (exists) { 172 | /* existed, lets truncate */ 173 | truncate = TRUE; 174 | break; 175 | } 176 | /* fall through */ 177 | case MODE_READWRITE: 178 | if (!exists) { 179 | /* did not exist, lets create */ 180 | CHECKWRITABLE(DOSFALSE); 181 | if (FSOP mknod) { 182 | error = Fbx_mknod(fs, fullpath, DEFAULT_PERMS|S_IFREG, 0); 183 | if (error) { 184 | fs->r2 = FbxFuseErrno2Error(error); 185 | return DOSFALSE; 186 | } 187 | error = Fbx_getattr(fs, fullpath, &statbuf); 188 | if (error) { 189 | fs->r2 = FbxFuseErrno2Error(error); 190 | return DOSFALSE; 191 | } 192 | } else { 193 | e = FbxSetupEntry(fs, fullpath, ETYPE_FILE, 0); 194 | if (e == FALSE) return DOSFALSE; 195 | lock2 = FbxLockEntry(fs, e, lockmode); 196 | if (lock2 == NULL) { 197 | FbxCleanupEntry(fs, e); 198 | return DOSFALSE; 199 | } 200 | if (FbxCreateOpenLock(fs, fh, lock2, DEFAULT_PERMS) == DOSFALSE) { 201 | FbxEndLock(fs, lock2); 202 | FbxCleanupEntry(fs, e); 203 | return DOSFALSE; 204 | } 205 | } 206 | DEBUGF("FbxOpenFile: new file created ok\n"); 207 | } 208 | break; 209 | default: 210 | fs->r2 = ERROR_BAD_NUMBER; 211 | return DOSFALSE; 212 | } 213 | 214 | if (truncate) { 215 | CHECKWRITABLE(DOSFALSE); 216 | error = Fbx_truncate(fs, fullpath, 0); 217 | if (error) { 218 | fs->r2 = FbxFuseErrno2Error(error); 219 | return DOSFALSE; 220 | } 221 | DEBUGF("FbxOpenFile: cleared ok\n"); 222 | } 223 | 224 | if (e == NULL) { 225 | e = FbxSetupEntry(fs, fullpath, ETYPE_FILE, statbuf.st_ino); 226 | if (e == NULL) return DOSFALSE; 227 | } 228 | 229 | if (lock2 == NULL) { 230 | lock2 = FbxLockEntry(fs, e, lockmode); 231 | if (lock2 == NULL) { 232 | FbxCleanupEntry(fs, e); 233 | return DOSFALSE; 234 | } 235 | 236 | if (FbxOpenLock(fs, fh, lock2) == DOSFALSE) { 237 | FbxEndLock(fs, lock2); 238 | FbxCleanupEntry(fs, e); 239 | return DOSFALSE; 240 | } 241 | } 242 | 243 | if (!exists || truncate) { 244 | FbxTryResolveNotify(fs, e); 245 | lock2->flags |= LOCKFLAG_MODIFIED; 246 | FbxSetModifyState(fs, 1); 247 | } 248 | 249 | fs->r2 = 0; 250 | return DOSTRUE; 251 | } 252 | 253 | -------------------------------------------------------------------------------- /src/dofmt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2025 Fredrik Wikstrom 3 | * 4 | * This code is released under AROS PUBLIC LICENSE 1.1 5 | * See the file LICENSE.APL 6 | */ 7 | 8 | #ifndef NODEBUG 9 | #include "filesysbox_internal.h" 10 | #include 11 | #include 12 | #include 13 | 14 | static void reverse(char *str, size_t len) { 15 | char *start = str; 16 | char *end = str + len - 1; 17 | char tmp; 18 | 19 | while (start < end) { 20 | tmp = *end; 21 | *end-- = *start; 22 | *start++ = tmp; 23 | } 24 | } 25 | 26 | 27 | static size_t itoa(unsigned num, char *dst, unsigned base, 28 | char issigned, char addplus, char uppercase) 29 | { 30 | char a = uppercase ? 'A' : 'a'; 31 | char negative = FALSE; 32 | char *d = dst; 33 | size_t len; 34 | 35 | if (num == 0) { 36 | *d++ = '0'; 37 | return d - dst; 38 | } 39 | 40 | if (issigned && (int)num < 0 && base == 10) { 41 | negative = TRUE; 42 | num = -num; 43 | } 44 | 45 | while (num != 0) { 46 | unsigned rem = num % base; 47 | num /= base; 48 | *d++ = (rem > 9) ? (rem - 10 + a) : (rem + '0'); 49 | } 50 | 51 | if (negative) 52 | *d++ = '-'; 53 | else if (addplus) 54 | *d++ = '+'; 55 | 56 | len = d - dst; 57 | reverse(dst, len); 58 | return len; 59 | } 60 | 61 | static size_t lltoa(unsigned long long num, char *dst, unsigned base, 62 | char issigned, char addplus, char uppercase) 63 | { 64 | char a = uppercase ? 'A' : 'a'; 65 | char negative = FALSE; 66 | char *d = dst; 67 | size_t len; 68 | 69 | if (num == 0) { 70 | *d++ = '0'; 71 | return d - dst; 72 | } 73 | 74 | if (issigned && (signed long long)num < 0 && base == 10) { 75 | negative = TRUE; 76 | num = -num; 77 | } 78 | 79 | while (num != 0) { 80 | unsigned rem = num % base; 81 | num /= base; 82 | *d++ = (rem > 9) ? (rem - 10 + a) : (rem + '0'); 83 | } 84 | 85 | if (negative) 86 | *d++ = '-'; 87 | else if (addplus) 88 | *d++ = '+'; 89 | 90 | len = d - dst; 91 | reverse(dst, len); 92 | return len; 93 | } 94 | 95 | #define PUTC(ch) \ 96 | do { \ 97 | if (cb((ch), cb_data) == 0) \ 98 | count++; \ 99 | else \ 100 | return -1; \ 101 | } while (0) 102 | 103 | int FbxDoFmt(fbx_putc_cb cb, void *cb_data, const char *fmt, va_list arg) { 104 | char ch; 105 | int count = 0; 106 | 107 | while ((ch = *fmt++) != '\0') { 108 | if (ch != '%') { 109 | PUTC(ch); 110 | } else { 111 | char left = FALSE; 112 | char addplus = FALSE; 113 | char alternate = FALSE; 114 | char lead = ' '; 115 | size_t width = 0; 116 | size_t limit = 0; 117 | char longlong = FALSE; 118 | char uppercase; 119 | char tmp[128]; 120 | const char *src; 121 | size_t len; 122 | 123 | if ((ch = *fmt++) == '\0') 124 | return count; 125 | 126 | while (TRUE) { 127 | if (ch == '-') 128 | left = TRUE; 129 | else if (ch == '+') 130 | addplus = TRUE; 131 | else if (ch == '#') 132 | alternate = TRUE; 133 | else if (ch == '0') 134 | lead = '0'; 135 | else 136 | break; 137 | if ((ch = *fmt++) == '\0') 138 | return count; 139 | } 140 | 141 | while (ch >= '0' && ch <= '9') { 142 | width = 10 * width + (ch - '0'); 143 | if ((ch = *fmt++) == '\0') 144 | return count; 145 | } 146 | 147 | if (ch == '.') { 148 | if ((ch = *fmt++) == '\0') 149 | return count; 150 | 151 | while (ch >= '0' && ch <= '9') { 152 | limit = 10 * limit + (ch - '0'); 153 | if ((ch = *fmt++) == '\0') 154 | return count; 155 | } 156 | } 157 | 158 | if (ch == 'l' || ch == 'h') { 159 | if ((ch = *fmt++) == '\0') 160 | return count; 161 | if (ch == 'l') { 162 | longlong = TRUE; 163 | if ((ch = *fmt++) == '\0') 164 | return count; 165 | } 166 | } 167 | 168 | switch (ch) { 169 | case '%': 170 | PUTC('%'); 171 | break; 172 | case 'D': 173 | case 'd': 174 | case 'I': 175 | case 'i': 176 | uppercase = (ch == 'D' || ch == 'I') ? TRUE : FALSE; 177 | if (longlong) 178 | len = lltoa(va_arg(arg, long long), tmp, 10, TRUE, addplus, uppercase); 179 | else 180 | len = itoa(va_arg(arg, int), tmp, 10, TRUE, addplus, uppercase); 181 | 182 | src = tmp; 183 | if (width > len) 184 | width -= len; 185 | else 186 | width = 0; 187 | 188 | if (!left) 189 | while (width--) 190 | PUTC(lead); 191 | 192 | while (len--) 193 | PUTC(*src++); 194 | 195 | if (left) 196 | while (width--) 197 | PUTC(' '); 198 | break; 199 | case 'U': 200 | case 'u': 201 | uppercase = (ch == 'X') ? TRUE : FALSE; 202 | if (longlong) 203 | len = lltoa(va_arg(arg, long long), tmp, 10, FALSE, addplus, uppercase); 204 | else 205 | len = itoa(va_arg(arg, int), tmp, 10, FALSE, addplus, uppercase); 206 | 207 | src = tmp; 208 | if (width > len) 209 | width -= len; 210 | else 211 | width = 0; 212 | 213 | if (!left) 214 | while (width--) 215 | PUTC(lead); 216 | 217 | while (len--) 218 | PUTC(*src++); 219 | 220 | if (left) 221 | while (width--) 222 | PUTC(' '); 223 | break; 224 | case 'X': 225 | case 'x': 226 | uppercase = (ch == 'X') ? TRUE : FALSE; 227 | if (longlong) 228 | len = lltoa(va_arg(arg, long long), tmp, 16, FALSE, addplus, uppercase); 229 | else 230 | len = itoa(va_arg(arg, int), tmp, 16, FALSE, addplus, uppercase); 231 | 232 | src = tmp; 233 | if (width > len) 234 | width -= len; 235 | else 236 | width = 0; 237 | 238 | if (!left) 239 | while (width--) 240 | PUTC(lead); 241 | 242 | while (len--) 243 | PUTC(*src++); 244 | 245 | if (left) 246 | while (width--) 247 | PUTC(' '); 248 | break; 249 | case 'P': 250 | case 'p': 251 | uppercase = (ch == 'P') ? TRUE : FALSE; 252 | if (longlong) 253 | len = lltoa(va_arg(arg, long long), tmp, 16, FALSE, FALSE, uppercase); 254 | else 255 | len = itoa(va_arg(arg, int), tmp, 16, FALSE, FALSE, uppercase); 256 | 257 | src = tmp; 258 | width = 8; 259 | lead = '0'; 260 | if (width > len) 261 | width -= len; 262 | else 263 | width = 0; 264 | 265 | if (alternate && tmp[0] != '0') { 266 | PUTC('0'); 267 | PUTC('x'); 268 | } 269 | 270 | while (width--) 271 | PUTC(lead); 272 | 273 | while (len--) 274 | PUTC(*src++); 275 | break; 276 | case 'S': 277 | case 's': 278 | src = va_arg(arg, const char *); 279 | if (src == NULL) 280 | src = "(null)"; 281 | 282 | len = strlen(src); 283 | 284 | if (limit != 0) 285 | len = min(len, limit); 286 | 287 | if (width > len) 288 | width -= len; 289 | else 290 | width = 0; 291 | 292 | if (!left) 293 | while (width--) 294 | PUTC(' '); 295 | 296 | while (len--) 297 | PUTC(*src++); 298 | 299 | if (left) 300 | while (width--) 301 | PUTC(' '); 302 | break; 303 | } 304 | } 305 | } 306 | 307 | return count; 308 | } 309 | #endif /* !NODEBUG */ 310 | 311 | --------------------------------------------------------------------------------