aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2017-05-15 19:19:10 +0100
committerSimon Tatham <anakin@pobox.com>2017-05-15 19:19:10 +0100
commitb19fd4ee7798a4948f5f47fafd89d67576a4642a (patch)
treeedc0d6e2cca2d8ae5bb27ab7e74262e22078f9ee
parentd6e5f7ae7b48fd09a366a6fa7efaf9b72d40275f (diff)
downloadwix-on-linux-b19fd4ee7798a4948f5f47fafd89d67576a4642a.tar.gz
wix-on-linux-b19fd4ee7798a4948f5f47fafd89d67576a4642a.tar.bz2
wix-on-linux-b19fd4ee7798a4948f5f47fafd89d67576a4642a.zip
Build cab files using lcab.
-rw-r--r--Makefile.wixfakelibs4
-rw-r--r--fake-lib.c51
-rw-r--r--fake-lib.h9
-rw-r--r--fake-msi.c27
-rw-r--r--fake-winterop.c105
5 files changed, 94 insertions, 102 deletions
diff --git a/Makefile.wixfakelibs b/Makefile.wixfakelibs
index 7a3b8ef..f53c539 100644
--- a/Makefile.wixfakelibs
+++ b/Makefile.wixfakelibs
@@ -10,9 +10,9 @@ all: libwinterop.so.la libmsi.so.la
10%.lo: %.c 10%.lo: %.c
11 libtool --mode=compile gcc -c $^ 11 libtool --mode=compile gcc -c $^
12 12
13libwinterop.so.la: fake-winterop.lo 13libwinterop.so.la: fake-winterop.lo fake-lib.lo
14 14
15libmsi.so.la: fake-msi.lo 15libmsi.so.la: fake-msi.lo fake-lib.lo
16 16
17clean: 17clean:
18 rm -rf .libs 18 rm -rf .libs
diff --git a/fake-lib.c b/fake-lib.c
index f8dbea4..9255005 100644
--- a/fake-lib.c
+++ b/fake-lib.c
@@ -11,7 +11,9 @@
11#include <sys/wait.h> 11#include <sys/wait.h>
12#include <unistd.h> 12#include <unistd.h>
13 13
14static char *ascii(const char16_t *wstr, bool translate_slashes) 14#include "fake-lib.h"
15
16char *ascii(const char16_t *wstr, bool translate_slashes)
15{ 17{
16 size_t len = 0; 18 size_t len = 0;
17 for (const char16_t *wp = wstr; *wp; wp++) 19 for (const char16_t *wp = wstr; *wp; wp++)
@@ -26,7 +28,7 @@ static char *ascii(const char16_t *wstr, bool translate_slashes)
26 return ret; 28 return ret;
27} 29}
28 30
29static void system_argv(const char *cmd, ...) 31void system_argv(const char *cmd, ...)
30{ 32{
31 int nargs, nchars; 33 int nargs, nchars;
32 const char *word; 34 const char *word;
@@ -68,3 +70,48 @@ static void system_argv(const char *cmd, ...)
68 if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) 70 if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0))
69 errx(1, "subcommand failed"); 71 errx(1, "subcommand failed");
70} 72}
73
74void c16cpy(char16_t *out, uint32_t *outsize, char *s)
75{
76 uint32_t retlen = 0;
77 while (retlen < *outsize) {
78 char16_t c = (out[retlen] = (unsigned char)*s++);
79 if (!c)
80 break;
81 retlen++;
82 }
83 *outsize = retlen;
84}
85
86void *smalloc(size_t size)
87{
88 void *toret = malloc(size);
89 if (!toret)
90 errx(1, "out of memory");
91 return toret;
92}
93
94char *dupcat(const char *str, ...)
95{
96 va_list ap;
97 const char *p;
98 char *out, *outp;
99 size_t len;
100
101 len = 1;
102 va_start(ap, str);
103 for (p = str; p; p = va_arg(ap, const char *))
104 len += strlen(p);
105 va_end(ap);
106
107 out = snewn(len, char);
108 outp = out;
109 va_start(ap, str);
110 for (p = str; p; p = va_arg(ap, const char *)) {
111 strcpy(outp, p);
112 outp += strlen(p);
113 }
114 va_end(ap);
115
116 return out;
117}
diff --git a/fake-lib.h b/fake-lib.h
new file mode 100644
index 0000000..65fed63
--- /dev/null
+++ b/fake-lib.h
@@ -0,0 +1,9 @@
1char *ascii(const char16_t *wstr, bool translate_slashes);
2void system_argv(const char *cmd, ...);
3void c16cpy(char16_t *out, uint32_t *outsize, char *s);
4void *smalloc(size_t size);
5char *dupcat(const char *str, ...);
6
7#define snew(type) ((type *)smalloc(sizeof(type)))
8#define snewn(n,type) ((type *)smalloc((n)*sizeof(type)))
9#define sfree(ptr) free(ptr)
diff --git a/fake-msi.c b/fake-msi.c
index 3bf1475..59e0a4b 100644
--- a/fake-msi.c
+++ b/fake-msi.c
@@ -9,32 +9,7 @@
9 9
10#include <fcntl.h> 10#include <fcntl.h>
11 11
12static char *ascii(const char16_t *wstr, bool translate_slashes) 12#include "fake-lib.h"
13{
14 size_t len = 0;
15 for (const char16_t *wp = wstr; *wp; wp++)
16 len++;
17 char *ret = malloc(len + 1);
18 char *p = ret;
19 for (const char16_t *wp = wstr; *wp; wp++)
20 *p++ = (*wp == '\\' && translate_slashes ? '/' :
21 *wp < 0x80 ? *wp :
22 '?');
23 *p = '\0';
24 return ret;
25}
26
27static void c16cpy(char16_t *out, uint32_t *outsize, char *s)
28{
29 uint32_t retlen = 0;
30 while (retlen < *outsize) {
31 char16_t c = (out[retlen] = (unsigned char)*s++);
32 if (!c)
33 break;
34 retlen++;
35 }
36 *outsize = retlen;
37}
38 13
39uint32_t MsiGetFileVersionW(const char16_t *filename, 14uint32_t MsiGetFileVersionW(const char16_t *filename,
40 char16_t *version, uint32_t *version_size, 15 char16_t *version, uint32_t *version_size,
diff --git a/fake-winterop.c b/fake-winterop.c
index ae4b8ef..d792553 100644
--- a/fake-winterop.c
+++ b/fake-winterop.c
@@ -11,63 +11,7 @@
11#include <sys/wait.h> 11#include <sys/wait.h>
12#include <unistd.h> 12#include <unistd.h>
13 13
14static char *ascii(const char16_t *wstr, bool translate_slashes) 14#include "fake-lib.h"
15{
16 size_t len = 0;
17 for (const char16_t *wp = wstr; *wp; wp++)
18 len++;
19 char *ret = malloc(len + 1);
20 char *p = ret;
21 for (const char16_t *wp = wstr; *wp; wp++)
22 *p++ = (*wp == '\\' && translate_slashes ? '/' :
23 *wp < 0x80 ? *wp :
24 '?');
25 *p = '\0';
26 return ret;
27}
28
29static void system_argv(const char *cmd, ...)
30{
31 int nargs, nchars;
32 const char *word;
33 va_list ap;
34
35 va_start(ap, cmd);
36 nargs = 1; /* terminating NULL */
37 nchars = 0;
38 for (word = cmd; word; word = va_arg(ap, const char *)) {
39 nargs++;
40 nchars += 1 + strlen(word);
41 }
42 va_end(ap);
43
44 char *args[nargs], chars[nchars];
45 char **argp = args, *charp = chars;
46 va_start(ap, cmd);
47 for (word = cmd; word; word = va_arg(ap, const char *)) {
48 *argp++ = charp;
49 strcpy(charp, word);
50 charp += 1 + strlen(word);
51 }
52 va_end(ap);
53 *argp++ = NULL;
54
55 pid_t pid = fork();
56 if (pid < 0)
57 err(1, "fork");
58
59 if (pid == 0) {
60 execvp(args[0], args);
61 warn("execvp");
62 _exit(127);
63 }
64
65 int status;
66 if (waitpid(pid, &status, 0) != pid)
67 err(1, "waitpid");
68 if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0))
69 errx(1, "subcommand failed");
70}
71 15
72uint32_t HashPublicKeyInfo(void *pCertContext, 16uint32_t HashPublicKeyInfo(void *pCertContext,
73 void *rgbSubjectKeyIdentifier, 17 void *rgbSubjectKeyIdentifier,
@@ -81,44 +25,61 @@ uint32_t ResetAcls(const char16_t **pwzFiles, uint32_t cFiles)
81 return 0; 25 return 0;
82} 26}
83 27
28typedef struct CabCreateContext {
29 char *tempdir;
30 char *outdir;
31 char *outfile;
32} CabCreateContext;
33
84uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir, 34uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir,
85 uint32_t dwMaxFiles, uint32_t dwMaxSize, 35 uint32_t dwMaxFiles, uint32_t dwMaxSize,
86 uint32_t dwMaxThresh, int compression, 36 uint32_t dwMaxThresh, int compression,
87 void **out_ctx) 37 CabCreateContext **out_ctx)
88{ 38{
89 fprintf(stderr, "CreateCabBegin(\"%s\", \"%s\", ...)\n", 39 CabCreateContext *ctx = snew(CabCreateContext);
90 ascii(wzCab, true), ascii(wzCabDir, true)); 40 ctx->outdir = ascii(wzCabDir, true);
91 *out_ctx = (void *)10; 41 ctx->outfile = dupcat(ctx->outdir, "/",
42 ascii(wzCab, true), (const char *)NULL);
43 ctx->tempdir = snewn(20 + strlen(ctx->outdir), char);
44 sprintf(ctx->tempdir, "%s/cabXXXXXX", ctx->outdir);
45 if (!mkdtemp(ctx->tempdir))
46 err(1, "mkdtemp");
47 *out_ctx = ctx;
92 return 0; 48 return 0;
93} 49}
94 50
95uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken, 51uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken,
96 void *pmfHash, void *ctx) 52 void *pmfHash, CabCreateContext *ctx)
97{ 53{
98 fprintf(stderr, "CreateCabAddFile(%p,%s,%s)\n", ctx, 54 char *file = ascii(wzFile, true);
99 ascii(wzFile, true), ascii(wzToken, false)); 55 char *file_abs = realpath(file, NULL);
56 char *cabname = ascii(wzToken, true);
57 char *cab_abs = dupcat(ctx->tempdir, "/", cabname, (const char *)NULL);
58 printf("CreateCabAddFile: %s <- %s\n", ctx->outfile, file_abs);
59 if (symlink(file_abs, cab_abs) < 0)
60 err(1, "symlink");
100 return 0; 61 return 0;
101} 62}
102 63
103uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles, 64uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles,
104 const char16_t *const *pwzTokens, 65 const char16_t *const *pwzTokens,
105 void *pmfHash, uint32_t cFiles, void *hContext) 66 void *pmfHash, uint32_t cFiles,
67 CabCreateContext *ctx)
106{ 68{
107 fprintf(stderr, "CreateCabAddFiles!\n"); 69 for (uint32_t i = 0; i < cFiles; i++)
70 CreateCabAddFile(pwzFiles[i], pwzTokens[i], pmfHash, ctx);
108 return 0; 71 return 0;
109} 72}
110 73
111uint32_t CreateCabFinish(void *hContext, void *newCabNamesCallBackAddress) 74uint32_t CreateCabFinish(CabCreateContext *ctx, void (*split_callback)(void))
112{ 75{
113 /* FIXME: newCabNamesCallBackAddress is actually a fn ptr of some kind */ 76 system_argv("lcab", "-r", "-n", ctx->tempdir, ctx->outfile,
114 fprintf(stderr, "CabCFinish(%p,%p)!\n", 77 (const char *)NULL);
115 hContext, newCabNamesCallBackAddress);
116 return 0; 78 return 0;
117} 79}
118 80
119void CreateCabCancel(void *hContext) 81void CreateCabCancel(void *hContext)
120{ 82{
121 fprintf(stderr, "CabCCancel(%p)!\n", hContext);
122} 83}
123 84
124uint32_t ExtractCabBegin(void) 85uint32_t ExtractCabBegin(void)
@@ -145,7 +106,7 @@ uint32_t EnumerateCabBegin(void)
145 106
146uint32_t EnumerateCab(const char16_t *wzCabinet, void *pfnNotify) 107uint32_t EnumerateCab(const char16_t *wzCabinet, void *pfnNotify)
147{ 108{
148 /* FIXME: fpnNotify looks like a fn ptr again */ 109 /* FIXME: pfnNotify looks like a fn ptr again */
149 fprintf(stderr, "EnumerateCab!\n"); 110 fprintf(stderr, "EnumerateCab!\n");
150 return 0; 111 return 0;
151} 112}