aboutsummaryrefslogtreecommitdiff
path: root/fake-msi.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2017-05-18 08:26:44 +0100
committerSimon Tatham <anakin@pobox.com>2017-05-18 08:27:29 +0100
commita568db73a69a934c09ad5c95f5a218fb6b869298 (patch)
tree301b9b7c78e132bad0955c8c9cb9ccc49999abae /fake-msi.c
parent7ca5ab5ef2eb8bb0f65aedf11eb74ad2ada78a19 (diff)
downloadwix-on-linux-a568db73a69a934c09ad5c95f5a218fb6b869298.tar.gz
wix-on-linux-a568db73a69a934c09ad5c95f5a218fb6b869298.tar.bz2
wix-on-linux-a568db73a69a934c09ad5c95f5a218fb6b869298.zip
Rename fake-msi.c to makemsi.c.
It's now a sensible source flie containing a set of routines that do something coherently connected to each other, so it doesn't deserve that 'fake-' prefix that I used for the previous monolithic files full of tangled-together stuff. While I'm here, I've also made up nicer (i.e. more distinguishable) random magic numbers for the structure-type disambiguation.
Diffstat (limited to 'fake-msi.c')
-rw-r--r--fake-msi.c212
1 files changed, 0 insertions, 212 deletions
diff --git a/fake-msi.c b/fake-msi.c
deleted file mode 100644
index 7bdcdc6..0000000
--- a/fake-msi.c
+++ /dev/null
@@ -1,212 +0,0 @@
1#include <assert.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <stdint.h>
5#include <stdbool.h>
6#include <stdarg.h>
7#include <string.h>
8#include <uchar.h>
9#include <err.h>
10
11#include <fcntl.h>
12#include <sys/mman.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <unistd.h>
16
17#include "memory.h"
18#include "dupstr.h"
19#include "subproc.h"
20#include "uchars.h"
21
22typedef struct MsiTypePrefix {
23 enum { MAIN, VIEW, RECORD } type;
24} MsiTypePrefix;
25
26typedef struct MsiMainCtx {
27 MsiTypePrefix t;
28
29 char *tempdir;
30 char *outfile;
31
32 char **args;
33 int nargs, argsize;
34} MsiMainCtx;
35
36
37uint32_t MsiOpenDatabaseW(const char16_t *filename,
38 const char16_t *persist,
39 MsiMainCtx **out_ctx)
40{
41 MsiMainCtx *ctx = snew(MsiMainCtx);
42 ctx->t.type = MAIN;
43 ctx->outfile = ascii(filename, true);
44 close(open(ctx->outfile, O_CREAT | O_WRONLY, 0666));
45 ctx->outfile = realpath(ctx->outfile, NULL);
46 unlink(ctx->outfile);
47 ctx->tempdir = dupcat(ctx->outfile, "-msiXXXXXX", cNULL);
48 if (!mkdtemp(ctx->tempdir))
49 err(1, "%s: mkdtemp", ctx->tempdir);
50 ctx->nargs = 0;
51 ctx->argsize = 16;
52 ctx->args = snewn(ctx->argsize, char *);
53 ctx->args[ctx->nargs++] = dupstr("sh");
54 ctx->args[ctx->nargs++] = dupstr("-c");
55 ctx->args[ctx->nargs++] = dupstr("cd \"$0\" && \"$@\"");
56 ctx->args[ctx->nargs++] = dupstr(ctx->tempdir);
57 ctx->args[ctx->nargs++] = dupstr("msibuild");
58 ctx->args[ctx->nargs++] = dupstr(ctx->outfile);
59 *out_ctx = ctx;
60 return 0;
61}
62
63uint32_t MsiDatabaseImportW(MsiMainCtx *ctx, const char16_t *folder,
64 const char16_t *file)
65{
66 assert(ctx->t.type == MAIN);
67 system_argv("sh", "-c", "cd \"$0\" && cp \"$1\" \"$2\"",
68 ascii(folder, true), ascii(file, true), ctx->tempdir, cNULL);
69 if (ctx->nargs + 2 >= ctx->argsize) {
70 ctx->argsize = ctx->nargs * 5 / 4 + 16;
71 ctx->args = sresize(ctx->args, ctx->argsize, char *);
72 }
73 ctx->args[ctx->nargs++] = dupstr("-i");
74 ctx->args[ctx->nargs++] = dupcat(ctx->tempdir, "/", ascii(file, true),
75 cNULL);
76 return 0;
77}
78
79typedef struct MsiView {
80 MsiTypePrefix t;
81
82 FILE *fp;
83 char *targetdir;
84 MsiMainCtx *ctx;
85} MsiView;
86
87uint32_t MsiDatabaseOpenViewW(MsiMainCtx *ctx, const char16_t *query,
88 MsiView **outview)
89{
90 assert(ctx->t.type == MAIN);
91 MsiView *view = snew(MsiView);
92 view->t.type = VIEW;
93 view->ctx = ctx;
94 char *cquery = ascii(query, false);
95 if (!strcmp(cquery, "SELECT `Name`, `Data` FROM `_Streams`"))
96 view->fp = NULL; /* special case */
97 else {
98 if (!strcmp(cquery, "SELECT `Name`, `Data` FROM `Binary`")) {
99 view->fp = fopen(dupcat(ctx->tempdir, "/", "Binary.idt", cNULL),
100 "a");
101 view->targetdir = dupcat(ctx->tempdir, "/", "Binary", cNULL);
102 } else if (!strcmp(cquery, "SELECT `Name`, `Data` FROM `Icon`")) {
103 view->fp = fopen(dupcat(ctx->tempdir, "/", "Icon.idt", cNULL),
104 "a");
105 view->targetdir = dupcat(ctx->tempdir, "/", "Icon", cNULL);
106 } else
107 errx(1, "unrecognised query: %s", cquery);
108 if (!view->fp)
109 err(1, "open");
110 if (mkdir(view->targetdir, 0777) < 0)
111 err(1, "%s: mkdir", view->targetdir);
112 }
113 *outview = view;
114 return 0;
115}
116
117uint32_t MsiViewExecute(MsiView *view, void *params)
118{
119 assert(view->t.type == VIEW);
120 return 0;
121}
122
123typedef struct MsiRecord {
124 MsiTypePrefix t;
125
126 char *name, *data;
127} MsiRecord;
128
129MsiRecord *MsiCreateRecord(uint32_t nparams)
130{
131 MsiRecord *rec = snew(MsiRecord);
132 rec->t.type = RECORD;
133
134 if (nparams != 2)
135 errx(1, "bad MsiCreateRecord param count %u", (unsigned)nparams);
136 rec->name = rec->data = NULL;
137 return rec;
138}
139
140uint32_t MsiRecordSetStringW(MsiRecord *rec, uint32_t field, char16_t *value)
141{
142 assert(rec->t.type == RECORD);
143 if (field != 1)
144 errx(1, "bad MsiRecordSetString param index %u", (unsigned)field);
145 rec->name = ascii(value, false);
146 return 0;
147}
148
149uint32_t MsiRecordSetStreamW(MsiRecord *rec, uint32_t field, char16_t *path)
150{
151 assert(rec->t.type == RECORD);
152 if (field != 2)
153 errx(1, "bad MsiRecordSetStream param index %u", (unsigned)field);
154 rec->data = ascii(path, true);
155 return 0;
156}
157
158uint32_t MsiViewModify(MsiView *view, uint32_t mode, MsiRecord *rec)
159{
160 assert(view->t.type == VIEW);
161 assert(rec->t.type == RECORD);
162 if (view->fp) {
163 system_argv("sh", "-c", "cp \"$0\" \"$1\"/\"$2\"",
164 rec->data, view->targetdir, rec->name, cNULL);
165 fprintf(view->fp, "%s\t%s\r\n", rec->name, rec->name);
166 } else {
167 MsiMainCtx *ctx = view->ctx;
168 if (ctx->nargs + 3 >= ctx->argsize) {
169 ctx->argsize = ctx->nargs * 5 / 4 + 16;
170 ctx->args = sresize(ctx->args, ctx->argsize, char *);
171 }
172 ctx->args[ctx->nargs++] = dupstr("-a");
173 ctx->args[ctx->nargs++] = dupstr(rec->name);
174 ctx->args[ctx->nargs++] = dupstr(rec->data);
175 }
176 return 0;
177}
178
179uint32_t MsiCloseHandle(MsiTypePrefix *t)
180{
181 if (t->type == VIEW) {
182 MsiView *view = (MsiView *)t;
183 if (view->fp)
184 fclose(view->fp);
185 }
186 return 0;
187}
188
189uint32_t MsiDatabaseCommit(MsiMainCtx *ctx)
190{
191 assert(ctx->t.type == MAIN);
192 printf("commit:");
193 for (int i = 0; i < ctx->nargs; i++) {
194 printf(" '");
195 for (const char *p = ctx->args[i]; *p; p++) {
196 if (*p == '\'')
197 printf("'\\''");
198 else
199 putchar(*p);
200 }
201 printf("'");
202 }
203 printf("\n");
204
205 if (ctx->nargs + 1 >= ctx->argsize) {
206 ctx->argsize = ctx->nargs * 5 / 4 + 16;
207 ctx->args = sresize(ctx->args, ctx->argsize, char *);
208 }
209 ctx->args[ctx->nargs++] = NULL;
210 system_argv_array(ctx->args);
211 return 0;
212}