tools/build-pkg.c
static PKGIndexEntry *filelist_to_index(FileInfo *filelist, int nfiles,
                                        char **namebuf_ret,
                                        uint32_t *namesize_ret)
{
    PKGIndexEntry *index = NULL;
    char *namebuf = NULL;
    uint32_t namesize = 0;

    index = malloc(sizeof(*index) * nfiles);
    if (!index) {
        fprintf(stderr, "Out of memory for index\n");
        goto error_return;
    }

    for (int i = 0; i < nfiles; i++) {
        FILE *f = fopen(filelist[i].realfile, "rb");
        if (!f) {
            fprintf(stderr, "Failed to open %s", filelist[i].realfile);
            if (strcmp(filelist[i].realfile, filelist[i].pathname) != 0) {
                fprintf(stderr, " (for %s)", filelist[i].pathname);
            }
            fprintf(stderr, ": %s\n", strerror(errno));
            goto error_return;
        }
        if (fseek(f, 0, SEEK_END) != 0) {
            fprintf(stderr, "fseek(%s): %s\n", filelist[i].realfile,
                    strerror(errno));
            fclose(f);
            goto error_return;
        }
        const uint32_t filesize = ftell(f);
        fclose(f);

        if (filesize < compress_min_size) {
            filelist[i].flags &= ~PKGF_DEFLATED;
        }

        index[i].hash          = pkg_hash(filelist[i].pathname);
        index[i].nameofs_flags = namesize | filelist[i].flags;
        /*       offset will be set later. */
        index[i].datalen       = filesize;
        index[i].filesize      = filesize;

        const uint32_t thisnamelen = strlen(filelist[i].pathname) + 1;
        namebuf = realloc(namebuf, namesize + thisnamelen);
        if (!namebuf) {
            fprintf(stderr, "Out of memory for namebuf (%s)\n",
                    filelist[i].pathname);
            goto error_return;
        }
        memcpy(namebuf + namesize, filelist[i].pathname, thisnamelen);
        namesize += thisnamelen;
    }

    pkg_sort(index, nfiles, namebuf, 0, nfiles-1);
    for (int i = 0; i < nfiles; i++) {
        filelist[i].index_entry = -1;
        const uint32_t hash = pkg_hash(filelist[i].pathname);
        for (int j = 0; j < nfiles; j++) {
#define NAME(a)  (namebuf + PKG_NAMEOFS(index[(a)].nameofs_flags))
            if (index[j].hash == hash
             && stricmp(filelist[i].pathname, NAME(j)) == 0) {
                filelist[i].index_entry = j;
                break;
            }
#undef NAME
        }
        if (filelist[i].index_entry < 0) {
            fprintf(stderr, "File %s lost from index!\n",
                    filelist[i].pathname);
            goto error_return;
        }
    }

    *namebuf_ret = namebuf;
    *namesize_ret = namesize;
    return index;

  error_return:
    free(namebuf);
    free(index);
    return NULL;
}
/**
 * filelist_to_index:  Generate the package index from the file list.
 *
 * [Parameters]
 *     filelist: Array of FileInfo structures.
 *     nfiles: Number of files.
 *     namebuf_ret: Pointer to variables to receive the pathname data
 *         buffer (newly allocated).
 *     namesize_ret: Pointer to variables to receive the pathname data
 *         buffer size, in bytes.
 * [Return value]
 *     Newly-allocated array of PKGIndexEntry structures, or NULL on error.
 */
Generate the package index from the file list.
[Parameters]
filelist: Array of FileInfo structures.
nfiles: Number of files.
namebuf_ret: Pointer to variables to receive the pathname data
buffer (newly allocated).
namesize_ret: Pointer to variables to receive the pathname data
buffer size, in bytes.
[Return value]
Newly-allocated array of PKGIndexEntry structures, or NULL on error.
Generate the package index from the file list . [ Parameters ] filelist : Array of FileInfo structures . nfiles : Number of files . namebuf_ret : Pointer to variables to receive the pathname data buffer ( newly allocated ) . namesize_ret : Pointer to variables to receive the pathname data buffer size in bytes . [ Return value ] Newly - allocated array of PKGIndexEntry structures or NULL on error .
static PKGIndexEntry *filelist_to_index(FileInfo *filelist, int nfiles,
                                        char **namebuf_ret,
                                        uint32_t *namesize_ret)
{
    PKGIndexEntry *index = NULL;
    char *namebuf = NULL;
    uint32_t namesize = 0;
    index = malloc(sizeof(*index) * nfiles);
    if (!index) {
        fprintf(stderr, "Out of memory for index\n");
        goto error_return;
    }
    for (int i = 0; i < nfiles; i++) {
        FILE *f = fopen(filelist[i].realfile, "rb");
        if (!f) {
            fprintf(stderr, "Failed to open %s", filelist[i].realfile);
            if (strcmp(filelist[i].realfile, filelist[i].pathname) != 0) {
                fprintf(stderr, " (for %s)", filelist[i].pathname);
            }
            fprintf(stderr, ": %s\n", strerror(errno));
            goto error_return;
        }
        if (fseek(f, 0, SEEK_END) != 0) {
            fprintf(stderr, "fseek(%s): %s\n", filelist[i].realfile,
                    strerror(errno));
            fclose(f);
            goto error_return;
        }
        const uint32_t filesize = ftell(f);
        fclose(f);
        if (filesize < compress_min_size) {
            filelist[i].flags &= ~PKGF_DEFLATED;
        }
        index[i].hash          = pkg_hash(filelist[i].pathname);
        index[i].nameofs_flags = namesize | filelist[i].flags;
        index[i].datalen       = filesize;
        index[i].filesize      = filesize;
        const uint32_t thisnamelen = strlen(filelist[i].pathname) + 1;
        namebuf = realloc(namebuf, namesize + thisnamelen);
        if (!namebuf) {
            fprintf(stderr, "Out of memory for namebuf (%s)\n",
                    filelist[i].pathname);
            goto error_return;
        }
        memcpy(namebuf + namesize, filelist[i].pathname, thisnamelen);
        namesize += thisnamelen;
    }
    pkg_sort(index, nfiles, namebuf, 0, nfiles-1);
    for (int i = 0; i < nfiles; i++) {
        filelist[i].index_entry = -1;
        const uint32_t hash = pkg_hash(filelist[i].pathname);
        for (int j = 0; j < nfiles; j++) {
#define NAME(a)  (namebuf + PKG_NAMEOFS(index[(a)].nameofs_flags))
            if (index[j].hash == hash
             && stricmp(filelist[i].pathname, NAME(j)) == 0) {
                filelist[i].index_entry = j;
                break;
            }
#undef NAME
        }
        if (filelist[i].index_entry < 0) {
            fprintf(stderr, "File %s lost from index!\n",
                    filelist[i].pathname);
            goto error_return;
        }
    }
    *namebuf_ret = namebuf;
    *namesize_ret = namesize;
    return index;
  error_return:
    free(namebuf);
    free(index);
    return NULL;
}
static PKGIndexEntry * filelist_to_index ( FileInfo * filelist , int nfiles , char * * namebuf_ret , uint32_t * namesize_ret ) { PKGIndexEntry * index = NULL ; char * namebuf = NULL ; uint32_t namesize = 0 ; index = malloc ( sizeof ( * index ) * nfiles ) ; if ( ! index ) { fprintf ( stderr , " \n " ) ; goto error_return ; } for ( int i = 0 ; i < nfiles ; i ++ ) { FILE * f = fopen ( filelist [ i ] . realfile , " " ) ; if ( ! f ) { fprintf ( stderr , " " , filelist [ i ] . realfile ) ; if ( strcmp ( filelist [ i ] . realfile , filelist [ i ] . pathname ) != 0 ) { fprintf ( stderr , " " , filelist [ i ] . pathname ) ; } fprintf ( stderr , " \n " , strerror ( errno ) ) ; goto error_return ; } if ( fseek ( f , 0 , SEEK_END ) != 0 ) { fprintf ( stderr , " \n " , filelist [ i ] . realfile , strerror ( errno ) ) ; fclose ( f ) ; goto error_return ; } const uint32_t filesize = ftell ( f ) ; fclose ( f ) ; if ( filesize < compress_min_size ) { filelist [ i ] . flags &= ~ PKGF_DEFLATED ; } index [ i ] . hash = pkg_hash ( filelist [ i ] . pathname ) ; index [ i ] . nameofs_flags = namesize | filelist [ i ] . flags ; index [ i ] . datalen = filesize ; index [ i ] . filesize = filesize ; const uint32_t thisnamelen = strlen ( filelist [ i ] . pathname ) + 1 ; namebuf = realloc ( namebuf , namesize + thisnamelen ) ; if ( ! namebuf ) { fprintf ( stderr , " \n " , filelist [ i ] . pathname ) ; goto error_return ; } memcpy ( namebuf + namesize , filelist [ i ] . pathname , thisnamelen ) ; namesize += thisnamelen ; } pkg_sort ( index , nfiles , namebuf , 0 , nfiles - 1 ) ; for ( int i = 0 ; i < nfiles ; i ++ ) { filelist [ i ] . index_entry = -1 ; const uint32_t hash = pkg_hash ( filelist [ i ] . pathname ) ; for ( int j = 0 ; j < nfiles ; j ++ ) { #define NAME ( a )   (namebuf + PKG_NAMEOFS(index[(a)].nameofs_flags)) if ( index [ j ] . hash == hash && stricmp ( filelist [ i ] . pathname , NAME ( j ) ) == 0 ) { filelist [ i ] . index_entry = j ; break ; } #undef  NAME } if ( filelist [ i ] . index_entry < 0 ) { fprintf ( stderr , " \n " , filelist [ i ] . pathname ) ; goto error_return ; } } * namebuf_ret = namebuf ; * namesize_ret = namesize ; return index ; error_return : free ( namebuf ) ; free ( index ) ; return NULL ; }
filelist_to_index:  Generate the package index from the file list.
filelist_to_index : Generate the package index from the file list .
/*       offset will be set later. */