{"id":13812351,"url":"https://github.com/dlbeer/ufat","last_synced_at":"2026-03-07T23:08:08.674Z","repository":{"id":33966912,"uuid":"37703020","full_name":"dlbeer/ufat","owner":"dlbeer","description":"Low-memory feature-complete VFAT implementation","archived":false,"fork":false,"pushed_at":"2023-04-25T09:55:14.000Z","size":116,"stargazers_count":37,"open_issues_count":3,"forks_count":12,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-19T07:38:43.741Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"siddontang/ledisdb","license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dlbeer.png","metadata":{"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-19T05:17:30.000Z","updated_at":"2024-11-12T23:24:02.000Z","dependencies_parsed_at":"2024-08-04T04:02:16.317Z","dependency_job_id":"f72eef30-dcc5-4605-a440-b2da1af08e5d","html_url":"https://github.com/dlbeer/ufat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlbeer%2Fufat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlbeer%2Fufat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlbeer%2Fufat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dlbeer%2Fufat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dlbeer","download_url":"https://codeload.github.com/dlbeer/ufat/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254231279,"owners_count":22036339,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T04:00:51.031Z","updated_at":"2026-03-07T23:08:08.621Z","avatar_url":"https://github.com/dlbeer.png","language":"C","funding_links":[],"categories":["Storage"],"sub_categories":["Filesystems"],"readme":"uFAT\n====\n\nuFAT is small but feature-complete VFAT/FAT32 implementation. It\nsupports all basic filesystem operations and has minimal memory\nrequirements. Its key features are:\n\n  * No global data: can be used to access multiple filesystems\n    simultaneously without issue.\n\n  * Small memory footprint: only a few kB required for metadata\n    caching and long filename parsing (the cache size is configurable\n    and can be as low as 512 bytes).\n\n  * No heap allocation is used.\n\n  * Highly portable: no external dependencies except for a few\n    easily-implementable ANSI C functions (memcpy, memset, atoi).\n\n  * Unicode filenames are supported (via translation to and from UTF-8\n    for function call arguments).\n\n  * Supports reading, writing and creating FAT12, FAT16 and FAT32,\n    including long filenames.\n\nUsing uFAT as a library\n-----------------------\n\nThe interface to the underlying block device is abstract and specified\nthough a structure containing some key parameters and access functions:\n\n    typedef unsigned long long ufat_block_t;\n\n    struct ufat_device {\n      unsigned int  log2_block_size;\n      int   (*read)(const struct ufat_device *dev, ufat_block_t start,\n            ufat_block_t count, void *buffer);\n      int   (*write)(const struct ufat_device *dev, ufat_block_t start,\n            ufat_block_t count, const void *buffer);\n    };\n\nA pointer to the ``struct ufat_device`` is passed with each call to\n``read`` or ``write``, so driver-private data can be kept by embedding\nthe structure in a larger structure.\n\nAll ``ufat_block_t`` arguments are block indices relative to the\nbeginning of the partition. ``log2_block_size`` should be the base-2\nlogarithm of the block size (that is, ``1 \u003c\u003c log2_block_size`` is the\nactual block size in bytes). Having filled out a ``struct\nufat_device`` for the partition/device you want to access, Use\n``ufat_open``/``ufat_close`` to open and close the filesystem:\n\n    struct ufat_device dev;\n    struct ufat uf;\n    int err;\n\n    dev.log2_block_size = 9;\n    dev.read = my_read;\n    dev.write = my_write;\n\n    err = ufat_open(\u0026uf, \u0026dev);\n    if (err \u003c 0) {\n      fprintf(stderr, \"Error: %s\\n\", ufat_strerror(err));\n      return -1;\n    }\n\n    /* ... */\n\n    ufat_close(\u0026uf);\n\nNo memory is allocated when a filesystem is opened, but ``ufat_close``\nmust be called to flush caches if the filesystem has been modified.\n\nThere are three basic objects used by the filesystem implementation:\n\n``struct ufat_dirent``\n\n  ~ This represents a directory entry. It holds information on a file or\n    directory and contains the location of the entry on the underlying\n    device, attributes and file size (for regular files).\n\n``struct ufat_directory``\n\n  ~ This structure is a directory iterator. There are two ways to\n    construct this object: either by opening the root directory, or by\n    opening a subdirectory represented by a ``ufat_dirent`` using\n    ``ufat_open_subdir``. Iterating through the contents of a\n    directory returns a series of ``ufat_dirent`` structures.\n\n``struct ufat_file``\n\n  ~ This structure represents an open file. It is constructed from a\n    ``ufat_dirent`` via a call to ``ufat_open_file``.\n\nFunctions for manipulating the filesystem and the associated objects\nare detailed in the ``ufat.h`` header file. Examples may be found in\nthe included image-manipulation program (``main.c`` in the source\ndistribution).\n\nAll functions with ``int`` return types will return 0 on success or a\nnegative error code if there is a problem with the underlying\nfilesystem or device. These error codes can be translated into\nhuman-readable strings with ``ufat_strerror``. Error codes are\ndeclared as values for the enum ``ufat_error_t``.\n\nDirectories may be traversed by a series of\n``ufat_open_subdir``/``ufat_dir_find`` calls. For cases where a full\nslash-separated path is known, the following function is useful:\n\n    int ufat_dir_find_path(struct ufat_directory *dir,\n              const char *path, struct ufat_dirent *inf,\n              const char **path_out);\n\nIts arguments are:\n\n``dir``\n\n  ~ An open directory from which to start the search. This will in\n    most cases be the root directory, but it can be any subdirectory,\n    and the path given will be treated as relative to the initial\n    directory.\n\n``path``\n\n  ~ A slash-separated path, relative to the starting directory. Path\n    components may be separated by either a forward-slash or a\n    backslash. This path should be UTF-8 encoded.\n\n``inf``\n\n  ~ A pointer to a ``ufat_dirent`` which will be filled out with the\n    details of the file/directory found.\n\n``path_out``\n\n  ~ A pointer to the remainder of the path not processed if the file\n    could not be found.\n\nIf an IO or filesystem error occurs, a negative error code is\nreturned. When the given path identifies an existing file or\ndirectory, the structure pointed to ``inf`` is filled out and the\nfunction returns 0.\n\nIf the given path doesn't name an existing file or directory, 1 is\nreturned. In this case, ``inf`` is not filled out, but the pointer\npointed to by ``path_out`` will be filled out with a pointer to the\nremainder of ``path`` which was not processed.\n\nIn all cases, ``dir`` will be reinitialized to be an iterator for the\ndirectory where the search terminated.\n\nCopyright\n---------\n\nCopyright (C) 2012 TracMap Holdings Ltd\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n1. Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlbeer%2Fufat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdlbeer%2Fufat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdlbeer%2Fufat/lists"}