aboutsummaryrefslogtreecommitdiff
path: root/makecab.c
blob: 6c93a2255ae8f3ec4d6d131f6f2754499bfdaff3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <stdint.h>

#include <err.h>

#include "memory.h"
#include "dupstr.h"
#include "subproc.h"
#include "uchars.h"

typedef struct CabCreateContext {
    char *outfile;                     /* aliases one of args[] */

    char **args;
    int nargs, argsize;
} CabCreateContext;

uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir,
                        uint32_t dwMaxFiles, uint32_t dwMaxSize,
                        uint32_t dwMaxThresh, int compression,
                        CabCreateContext **out_ctx)
{
    CabCreateContext *ctx = snew(CabCreateContext);
    char *outdir = ascii(wzCabDir, true);
    char *cab = ascii(wzCab, true);
    ctx->outfile = dupcat(outdir, "/", cab, cNULL);
    sfree(cab);
    sfree(outdir);
    ctx->nargs = 0;
    ctx->argsize = 16;
    ctx->args = snewn(ctx->argsize, char *);
    ctx->args[ctx->nargs++] = dupcat(getenv("WIX"), "/", "makecab.py", cNULL);
    ctx->args[ctx->nargs++] = ctx->outfile;
    *out_ctx = ctx;
    return 0;
}

uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken,
                          void *pmfHash, CabCreateContext *ctx)
{
    char *file = ascii(wzFile, true);
    char *file_abs = realpath(file, NULL);
    char *cabname = ascii(wzToken, true);
    warnx("CreateCabAddFile: %s :: %s <- %s", ctx->outfile,
          cabname, file_abs);
    if (ctx->nargs + 1 >= ctx->argsize) {
        ctx->argsize = ctx->nargs * 5 / 4 + 16;
        ctx->args = sresize(ctx->args, ctx->argsize, char *);
    }
    ctx->args[ctx->nargs++] = cabname;
    ctx->args[ctx->nargs++] = file_abs;
    sfree(file);
    return 0;
}

uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles,
                           const char16_t *const *pwzTokens,
                           void *pmfHash, uint32_t cFiles,
                           CabCreateContext *ctx)
{
    for (uint32_t i = 0; i < cFiles; i++)
        CreateCabAddFile(pwzFiles[i], pwzTokens[i], pmfHash, ctx);
    return 0;
}

void CreateCabCancel(CabCreateContext *ctx)
{
    for (int i = 0; i < ctx->nargs; i++)
        sfree(ctx->args[i]);
    sfree(ctx->args);
    sfree(ctx);
}

uint32_t CreateCabFinish(CabCreateContext *ctx, void (*split_callback)(void))
{
    if (ctx->nargs + 1 >= ctx->argsize) {
        ctx->argsize = ctx->nargs * 5 / 4 + 16;
        ctx->args = sresize(ctx->args, ctx->argsize, char *);
    }
    ctx->args[ctx->nargs++] = NULL;
    system_argv_array(ctx->args);

    CreateCabCancel(ctx);              /* free everything */

    return 0;
}