Simple library for an undocumented archive format I'm writing a little library for some undocumented file formats. The original program uses a path string to find files in an archive and this function tries to do the same.
The archive contains a magic string, an offset into the file list, the data in the files and the file list itself. A entry in the filelist consists of a path (256 bytes long, 0-padded) and three numbers, the second one being the offset from the archive start to the entry file. The entries are sorted alphabetically respecting case; here are some mockup paths to demonstrate the ordering:
Entry/Graphics/Sprite.cgf
Entry/Sound/Ding.wav
Quit/Graphics/exit.cgf
_RAW8123

Here are the relevant utility functions and defines. These are defined in Utils.h and Utils.c, I've put them here together for context.
#define BYTESZE sizeof(char)

typedef unsigned int uint;
typedef unsigned char byte;

uint readU4L(FILE* file) {
    byte buf[4];
    fread(buf, BYTESZE, 4, file);
    return buf[3] &lt;&lt; 24 | buf[2] &lt;&lt; 16 | buf[1] &lt;&lt; 8 | buf[0];
}

Finally, here's the &quot;library&quot;:
// ====== BIGfile.h
#define BIG_MAGIC_LEN 7

#define BIG_SEEK_SUCC 1
#define BIG_SEEK_FAIL 0

typedef struct BIGFile {
    char magic[BIG_MAGIC_LEN];
    uint offset;
    FILE* read;

} BIGFile;

BIGFile* load_BIGFile(char* fpath);

int seekToEntry(BIGFile* bigfile, char* path);


// ====== BIGFile.c
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;

#include &quot;Utils.h&quot;
#include &quot;BIGFile.h&quot;

BIGFile* load_BIGFile(char* fpath) {
    BIGFile* bigfile = malloc(sizeof(BIGFile));

    fopen_s(&amp;(bigfile-&gt;read), fpath, &quot;rb&quot;);

    if (!bigfile-&gt;read) {
        printf(&quot;Can't open file.\n&quot;);
        return 0;
    }

    fread(bigfile-&gt;magic, BYTESZE, BIG_MAGIC_LEN, bigfile-&gt;read);
    bigfile-&gt;offset = readU4L(bigfile-&gt;read);
    return bigfile;
}

int seekToEntry(BIGFile* bigfile, char* path) {

    fseek(bigfile-&gt;read, bigfile-&gt;offset, SEEK_SET);
    
    byte buf[256];

    int pos = 0;

    // while not EOF, read string part
    while (fread(buf, BYTESZE, 256, bigfile-&gt;read)) {
        
        // seek over entry data
        fseek(bigfile-&gt;read, 12, SEEK_CUR);
        
        // loop until given path != read path
        while (path[pos]==buf[pos]) {
            pos++;

            // path has ended, so buf == path
            if (!path[pos]) {

                // seek back into entry data
                fseek(bigfile-&gt;read, -8, SEEK_CUR);

                // read unsigned little endian 4-byte int
                uint res = readU4L(bigfile-&gt;read);

                // seek there and return success
                fseek(bigfile-&gt;read, res, SEEK_SET);
                //printf(&quot;found at %d\n&quot;, res);
                return BIG_SEEK_SUCC;
            }
        }
        // path char is smaller than buf char
        // we seeked past where the entry could bem return failure
        if (path[pos]&lt;buf[pos]) {
            return BIG_SEEK_FAIL;
        }
    }
    // EOF, return failure
    return BIG_SEEK_FAIL;
}

I'd like some feedback on general style, as well as on the seekToEntry function, perhaps this can be improved somehow? Thanks in advance!
Overall, your coding style is pretty clean, but here are some improvement suggestions to make the code more robust and portable, as well as safer:
Use fixed sized integers
In C, sizeof(char) is guaranteed to be 1 by the standard, but sizeof(unsigned int) is not guaranteed to be 4.
Fortunately, C99 introduces fixed size integers such as uint32_t that is guaranteed to be 32 bit (4 bytes) defined in stdint.h.
Since you are using non standard fopen_s I assume you are not required to stick to ANSI C.
Add error checking
In the code you posted, you never check the return value of your file read operations or memory allocation operations.
You also never check the sanity of the data you read.
For a library, robust error handling is important, so you should always check if read operations success, and if data such as entry sizes or offsets are reasonable - match expected size / do not go past end of file.
On error, you should return one of several error codes you define for you library and list in documentation.
Reduce disk operations
You will probably not feel this in your testing, both due to modern hardware, small file size, and multiple caches on different levels, but your seekToEntry function is inefficient due to many back and forward disk operations (both seek and read).
There are two approaches here, which you can choose depending on how you want to trade memory for speed, and how would your library be used:

Preload the entire &quot;catalog&quot; of file entries in to array of structures in memory and search that when you need to find entry position in file.
Since your entries are guaranteed to be sorted, you may want to implement a more efficient search, maybe arrange them in a tree by prefix.

Since every entry has fixed size, read at least the current entry completely in to a structure.
If you don't want to load them all to memory in advance, at least load all data (name, size, offset) for each entry as you iterate, and save your self a bunch of seek operations.


Either approach will also give you the opportunity to create a documented structure for &quot;entry&quot; of this archive file, which will be good for you and your library users.
Create a name space
Since this is a library, it may be used in a big project with other libraries or many functions defined in the project it self.
You want to avoid name collision for your functions, structures, and defines.
Though C does not support special syntax for namespces, one convention for libraries is to use a fixed and consistent prefix to names followed by an underscore.
If your library is for handling &quot;Big File Archive&quot; you could prefix all your names with BFA_ like so: BFA_loadFile, BFA_seekToEntry.
Avoid non-standard functions
While MS may claim fopen_s is more secure, it is also non-standard, so if you or one of your library users ever switches compiler or OS, your library will no longer work.
You should use C standard fopen instead and just add proper error checking as specified above.
Also, there is no reason to reimplement strncmp as you do with your loops.
Unlike strcmp which is not safe if the string is not guaranteed to be null terminated, strncmp is perfectly safe for your use case where maximum length is known in advance.
Use consistent interface
It is hard to tell with only two functions, but you seem to have some difference in how your library functions work:
One returns an &quot;object&quot; (the BIGFile structure), another returns error / success codes instead.
While this is technically valid approach, it would be more consistent and comfortable for the user to have a unified interface where all functions would return the same thing - error codes.
If a function must also return a value for the user, such as a pointer to a structure, it should return it using one of the parameters.
Your open function could look like this:
/**
 * Opens an archive file and loads its header
 *
 * @param fpath   path to the archive file
 * @param header  place to return loaded header data if the file is successfully loaded (structure will be allocated by the function)
 * @return success / error status code
 */
int BFA_loadFile(char *fpath, BFA_FileHeader **header) {
    ...
}

Here, I also included one common method of documenting functions in libraries which can be used with automated tools such as doxygen to produce documentation files in HTML and other formats.